language-lawyer

Why is “cast from ‘X*’ to ‘Y’ loses precision” a hard error and what is suitable fix for legacy code

强颜欢笑 提交于 2020-01-03 09:41:07
问题 1. Why? Code like this used to work and it's kind of obvious what it is supposed to mean. Is the compiler even allowed (by the specification) to make it an error? I know that it's loosing precision and I would be happy with a warning. But it still has a well-defined semantics (at least for unsigned downsizing cast is defined) and the user just might want to do it. 2. Workaround I have legacy code that I don't want to refactor too much because it's rather tricky and already debugged. It is

std::is_constructible doesn't give the correct result [duplicate]

混江龙づ霸主 提交于 2020-01-03 09:03:12
问题 This question already has answers here : Why does is_constructible claim something is constructible when it isn't? (2 answers) Closed 3 years ago . Originated from this CodeReview topic: #include <cstddef> #include <algorithm> #include <iostream> #include <type_traits> #include <utility> template <typename T> class aggregate_wrapper : public T { private: using base = T; public: using aggregate_type = T; template <typename... Ts> aggregate_wrapper(Ts&&... xs) : base{std::forward<Ts>(xs)...} {

std::is_constructible doesn't give the correct result [duplicate]

时光毁灭记忆、已成空白 提交于 2020-01-03 09:02:15
问题 This question already has answers here : Why does is_constructible claim something is constructible when it isn't? (2 answers) Closed 3 years ago . Originated from this CodeReview topic: #include <cstddef> #include <algorithm> #include <iostream> #include <type_traits> #include <utility> template <typename T> class aggregate_wrapper : public T { private: using base = T; public: using aggregate_type = T; template <typename... Ts> aggregate_wrapper(Ts&&... xs) : base{std::forward<Ts>(xs)...} {

Initializing a dynamic array of non-default constructible objects

不羁岁月 提交于 2020-01-03 08:59:08
问题 The code below: struct Foo { Foo(int){} // no default constructor }; int main() { Foo* pFoo = new Foo[2]{1,2}; // OK in g++, fails in clang++! delete[] pFoo; } compiles in gcc, but fails in clang. Is the code above syntactically correct? 回答1: I'll turn @T.C. comment into an answer, so everyone sees what's going on without having to read through all of the comments. This is a clang bug, the code should be accepted: http://llvm.org/bugs/show_bug.cgi?id=22924 Related: http://wg21.link/cwg2102 来源

Is a statement void(); legal and what is it actually?

独自空忆成欢 提交于 2020-01-03 08:27:10
问题 I have a little piece of code which has a statement void(); int main() { void( ); // 1: parses fine in GCC 5.4.0 -Wpedantic // void; // 2: error declaration does not declare anything } What is 1 void() exactly? An anonymous function declaration? A type declaration? An empty expression? What makes 1 void() different from 2 void; ? I have read already: Is sizeof(void()) a legal expression? but there void() is considered a type in sizeof What does the void() in decltype(void()) mean exactly?

Does T have to be a complete type to be used in `std::declval<T>`?

こ雲淡風輕ζ 提交于 2020-01-03 07:59:10
问题 Consider this example (coming from here): #include <type_traits> #include <iostream> template <typename U> struct A { }; struct B { template <typename F = int> A<F> f() { return A<F>{}; } using default_return_type = decltype(std::declval<B>().f()); }; int main() { B::default_return_type x{}; std::cout << std::is_same< B::default_return_type, A<int>>::value; } It compiles with no errors on gcc9.2 but gcc7.2 and clang 10.0.0 complain about B not being complete. Clangs error is: prog.cc:11:58:

List-initialization of an array without temporaries - not working in GCC

你离开我真会死。 提交于 2020-01-03 07:25:06
问题 Consider the following contrived example struct A { A(int) {} A(const A&) = delete; ~A() {} }; struct B { A a[2] = {{1}, {2}}; }; int main() { B b; } It compiles fine in clang (any version) but not in GCC (any version, any standard >= C++11) <source>: In constructor 'constexpr B::B()': <source>:7:8: error: use of deleted function 'A::A(const A&)' struct B { ^ <source>:3:5: note: declared here A(const A&) = delete; ^ <source>: In function 'int main()': <source>:12:7: note: synthesized method

Friend function template with automatic return type deduction cannot access a private member

。_饼干妹妹 提交于 2020-01-03 07:19:15
问题 Sorry for how complicated the title of this question is; I tried to describe the minimal SSCCE I constructed for this problem. I have the following code: #include <iostream> namespace fizz { template<typename... Ts> class bar { public: template<int I, typename... Us> friend auto foo(const bar<Us...> &); private: int i = 123; }; template<int I, typename... Ts> auto foo(const bar<Ts...> & b) { return b.i; } } int main() { std::cout << fizz::foo<1>(fizz::bar<int, float>{}); } This code compiles

Different implementations of inline functions in different translation units

↘锁芯ラ 提交于 2020-01-02 21:56:12
问题 The C++ standard says this about ODR, as it applies to inline functions (emphasis mine): 3.2 One definition rule 3 Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program; no diagnostic required. The definition can appear explicitly in the program, it can be found in the standard or a user-defined library, or (when appropriate) it is implicitly defined (see 12.1, 12.4 and 12.8). An inline function shall be defined in every

Legal legacy code using pointers suddenly becomes UB

落爺英雄遲暮 提交于 2020-01-02 08:39:06
问题 Let's say we have this legacy code from C++98: bool expensiveCheck(); struct Foo; bool someFunc() { Foo *ptr = 0; if( expensiveCheck() ) ptr = new Foo; // doing something irrelevant here ... if( ptr ) { // using foo } delete ptr; return ptr; // here we have UB(Undefined Behavior) in C++11 } So basically pointer here is used to keep dynamically allocated data and use it as a flag at the same time. For me it is readable code and I believe it is legal C++98 code. Now according to this questions: