language-lawyer

What is the “C++ ABI Specification” referred to in GCC's manual?

怎甘沉沦 提交于 2020-06-14 07:45:07
问题 I was looking at the GCC manual for C++, and I came across the following quote: Version 0 refers to the version conforming most closely to the C++ ABI specification. Therefore, the ABI obtained using version 0 will change in different versions of G++ as ABI bugs are fixed. (source) As can be seen, the above passage references some sort of seemingly standard C++ ABI. As I understand it, however, no such ABI exists. What is this passage talking about? A good answer will give as thorough an

Two-phase function template compilation: not *only* ADL is employed in the 2nd phase?

旧时模样 提交于 2020-06-14 06:33:47
问题 I'm wondering why the following code compiles. #include <iostream> template<class T> void print(T t) { std::cout << t; } namespace ns { struct A {}; } std::ostream& operator<<(std::ostream& out, ns::A) { return out << "hi!"; } int main() { print(ns::A{}); } I was under impression that at the instantiation point unqualified dependent names are looked-up via ADL only - which should not consider the global namespace. Am I wrong? 回答1: This is an interesting case. The workings of name lookup as

In C++, does the size of an enumeration have to be equal to the size of its underlying type?

橙三吉。 提交于 2020-06-14 04:07:54
问题 I often assume that size of an enumeration is the same as the size of its underlying type. But is it mandated by the standard? The standard (C++14, n4296) says that every enumeration has an underlying type (7.2/5). The standard also says that objects are represented as sequences of bytes, and that the size of an object is related to its representation: 3.9/4 The object representation of an object of type T is the sequence of N unsigned char objects taken up by the object of type T, where N

Can std::string::compare(const char*) throw an exception?

試著忘記壹切 提交于 2020-06-13 15:38:43
问题 This is overload (4) here In the "Exceptions" section, overloads 2,3,5,6 (which have pos1 and/or pos2 parameters) are named as throwing std::out_of_range . Overload (4) does not have "pos" parameters, but it's not marked noexcept . Is it up to the implementation whether it throws or not? In GCC 7's libstdc++, it calls char_traits<char>::length and char_traits<char>::compare . These don't seem to be able to throw, but aren't marked noexcept . 回答1: Except for destructors, swap functions, move

Can std::string::compare(const char*) throw an exception?

血红的双手。 提交于 2020-06-13 15:36:34
问题 This is overload (4) here In the "Exceptions" section, overloads 2,3,5,6 (which have pos1 and/or pos2 parameters) are named as throwing std::out_of_range . Overload (4) does not have "pos" parameters, but it's not marked noexcept . Is it up to the implementation whether it throws or not? In GCC 7's libstdc++, it calls char_traits<char>::length and char_traits<char>::compare . These don't seem to be able to throw, but aren't marked noexcept . 回答1: Except for destructors, swap functions, move

Recursive computation using variable templates - gcc vs clang

非 Y 不嫁゛ 提交于 2020-06-11 16:53:09
问题 Consider the following example: #include <cstdio> template <int N> int fib = fib<N - 1> + fib<N - 2>; template <> int fib<2> = 1; template <> int fib<1> = 1; int main() { std::printf("%d %d %d", fib<4>, fib<5>, fib<6>); } GCC 7.x, 8.x, 9.x, and 10.x all print out the expected result of 3 5 8 . Clang 5.x, 6.x, 7.x, 8.x, 9.x, and 10.x all print out 1 3 4 as a result. live example on godbolt.org Clang's behavior is surprising. Is there any subtle interaction between variable template

g++ and clang++ different behaviour with recursive initialization of a static member

僤鯓⒐⒋嵵緔 提交于 2020-06-11 16:09:54
问题 Given the following code: #include <iostream> template <std::size_t N> struct foo { static std::size_t value; }; template <> std::size_t foo<0>::value = 0u; template <size_t N> std::size_t foo<N>::value = 1u + foo<N - 1u>::value; int main() { std::cout << foo<3u>::value << ' ' << foo<2u>::value << ' ' << foo<1u>::value << ' ' << foo<0u>::value << std::endl; } where the static member value of the template struct foo is recursively initialized, I get different outputs from g++: 3 2 1 0 and from

g++ and clang++ different behaviour with recursive initialization of a static member

最后都变了- 提交于 2020-06-11 16:06:08
问题 Given the following code: #include <iostream> template <std::size_t N> struct foo { static std::size_t value; }; template <> std::size_t foo<0>::value = 0u; template <size_t N> std::size_t foo<N>::value = 1u + foo<N - 1u>::value; int main() { std::cout << foo<3u>::value << ' ' << foo<2u>::value << ' ' << foo<1u>::value << ' ' << foo<0u>::value << std::endl; } where the static member value of the template struct foo is recursively initialized, I get different outputs from g++: 3 2 1 0 and from

Canonical implementation of operator+ involves additional move constructor

半腔热情 提交于 2020-06-11 06:09:08
问题 Motivated by this question, I compared two different versions of an implementation of a binary operator+ in terms of operator+= . Consider we are inside the definition of class X . Version 1 friend X operator+(X lhs, const X& rhs) { lhs += rhs; return lhs; } Version 2 friend X operator+(const X& lhs, const X& rhs) { X temp(lhs); temp += rhs; return temp; } friend X operator+(X&& lhs, const X& rhs) { lhs += rhs; return std::move(lhs); } Where, in both cases, operator+= is defined as follows: X

Is it well defined to reference a variable before it's constructed

佐手、 提交于 2020-06-10 16:11:52
问题 This is similar in spirit to a question that was asked and answered for c . The comments there implied that a precise answer would be different for c++ , so here is a similar question for code written in c++ . Is the following program well defined? int f(int& b) { b = 42; return b; } int a { f(a) }; It seems all right to me, but on the other hand, how is a being constructed from a value that is computed by a function, that itself modifies a ? I'm having a chicken-and-egg feeling about this,