language-lawyer

Incomplete types as function parameters and return values

99封情书 提交于 2020-04-09 15:50:36
问题 The following code compiles successfully both with clang++ 5.0.0 and g++ 7.2 (with the -std=c++17 -Wall -Wextra -Werror -pedantic-errors -O0 compilation flags): struct Foo; struct Bar { Foo get() const; void set(Foo); }; struct Foo { }; Foo Bar::get() const { return {}; } void Bar::set(Foo) { } int main() { Bar bar{}; (void)bar.get(); bar.set(Foo{}); } Is it valid to use incomplete types as function parameters and return values? What does the C++ say on it? 回答1: In a function definition , you

Incomplete types as function parameters and return values

北战南征 提交于 2020-04-09 15:49:12
问题 The following code compiles successfully both with clang++ 5.0.0 and g++ 7.2 (with the -std=c++17 -Wall -Wextra -Werror -pedantic-errors -O0 compilation flags): struct Foo; struct Bar { Foo get() const; void set(Foo); }; struct Foo { }; Foo Bar::get() const { return {}; } void Bar::set(Foo) { } int main() { Bar bar{}; (void)bar.get(); bar.set(Foo{}); } Is it valid to use incomplete types as function parameters and return values? What does the C++ say on it? 回答1: In a function definition , you

What is the correct way to convert 2 bytes to a signed 16-bit integer?

纵然是瞬间 提交于 2020-04-08 18:49:26
问题 In this answer, zwol made this claim: The correct way to convert two bytes of data from an external source into a 16-bit signed integer is with helper functions like this: #include <stdint.h> int16_t be16_to_cpu_signed(const uint8_t data[static 2]) { uint32_t val = (((uint32_t)data[0]) << 8) | (((uint32_t)data[1]) << 0); return ((int32_t) val) - 0x10000u; } int16_t le16_to_cpu_signed(const uint8_t data[static 2]) { uint32_t val = (((uint32_t)data[0]) << 0) | (((uint32_t)data[1]) << 8); return

What is the correct way to convert 2 bytes to a signed 16-bit integer?

三世轮回 提交于 2020-04-08 18:48:32
问题 In this answer, zwol made this claim: The correct way to convert two bytes of data from an external source into a 16-bit signed integer is with helper functions like this: #include <stdint.h> int16_t be16_to_cpu_signed(const uint8_t data[static 2]) { uint32_t val = (((uint32_t)data[0]) << 8) | (((uint32_t)data[1]) << 0); return ((int32_t) val) - 0x10000u; } int16_t le16_to_cpu_signed(const uint8_t data[static 2]) { uint32_t val = (((uint32_t)data[0]) << 0) | (((uint32_t)data[1]) << 8); return

Events and multithreading once again

岁酱吖の 提交于 2020-04-07 16:11:10
问题 I'm worried about the correctness of the seemingly-standard pre-C#6 pattern for firing an event: EventHandler localCopy = SomeEvent; if (localCopy != null) localCopy(this, args); I've read Eric Lippert's Events and races and know that there is a remaining issue of calling a stale event handler, but my worry is whether the compiler/JITter is allowed to optimize away the local copy, effectively rewriting the code as if (SomeEvent != null) SomeEvent(this, args); with possible

How do I make an infinite empty loop that won't be optimized away?

落花浮王杯 提交于 2020-04-07 11:19:09
问题 The C11 standard appears to imply that iteration statements with constant controlling expressions should not be optimized out. I'm taking my advice from this answer, which specifically quotes section 6.8.5 from the draft standard: An iteration statement whose controlling expression is not a constant expression ... may be assumed by the implementation to terminate. In that answer it mentions that a loop like while(1) ; should not be subject to optimization. So...why does Clang/LLVM optimize

Inconsistent truncation of unsigned bitfield integer expressions between C++ and C in different compilers

徘徊边缘 提交于 2020-04-06 02:26:45
问题 Edit 2 : I was debugging a strange test failure when a function previously residing in a C++ source file but moved into a C file verbatim, started to return incorrect results. The MVE below allows to reproduce the problem with GCC. However, when I, on a whim, compiled the example with Clang (and later with VS), I got a different result! I cannot figure out whether to treat this as a bug in one of the compilers, or as manifestation of undefined result allowed by C or C++ standard. Strangely,

Templated delegating copy constructor in constant expressions

荒凉一梦 提交于 2020-03-21 17:55:34
问题 This question is motivated by this one. Consider the following code: struct B {}; struct S { B b; // #1 S() = default; template <typename ...dummy> // #2 constexpr S(const S&) {} template <typename ...dummy> // #3 constexpr S(S &other) : S(const_cast<const S&>(other)) // #4 {} }; S s; constexpr S f() {return s;} int main() { constexpr auto x = f(); } GCC compiles this code successfully, but Clang rejects it (Example on Godbolt.org). The error message produced by Clang is <source>:21:20: error

Templated delegating copy constructor in constant expressions

本小妞迷上赌 提交于 2020-03-21 17:55:12
问题 This question is motivated by this one. Consider the following code: struct B {}; struct S { B b; // #1 S() = default; template <typename ...dummy> // #2 constexpr S(const S&) {} template <typename ...dummy> // #3 constexpr S(S &other) : S(const_cast<const S&>(other)) // #4 {} }; S s; constexpr S f() {return s;} int main() { constexpr auto x = f(); } GCC compiles this code successfully, but Clang rejects it (Example on Godbolt.org). The error message produced by Clang is <source>:21:20: error

Partial template specialization with mismatching `int` and `size_t` not compiling

為{幸葍}努か 提交于 2020-03-21 11:33:57
问题 With reference to the following code #include <utility> #include <cassert> template <typename T> struct Wot; template <int... ints> struct Wot<std::index_sequence<ints...>> {}; int main() { assert(sizeof(Wot<std::index_sequence<1, 2, 3>>) == 1); } This works on clang but does not work on gcc, when I change the type of the partial specialization to accept std::size_t in the index sequence however it works. Who is right? Clang or gcc? See this in action here https://wandbox.org/permlink