Today's episode of “something I didn't know about C++”:
class whynot { friend void; };
class whynot { friend void; };
Today's episode of "something I didn't know about C99":
int derp(int arr[static const restrict volatile 5]);
I knew `static 5` meant non-NULL, at least 5 elements.
Didn't know:
∙ const: always called with same array
∙ restrict: arrays don't alias
∙ volatile: NOTHING
int derp(int arr[static const restrict volatile 5]);
I knew `static 5` meant non-NULL, at least 5 elements.
Didn't know:
∙ const: always called with same array
∙ restrict: arrays don't alias
∙ volatile: NOTHING

Today's episode of "something I didn't know about C99":
error: parameter name omitted
int main(int, char**) {
^
All function parameters must be named
error: parameter name omitted
int main(int, char**) {
^
All function parameters must be named

Today's episode of "something I didn't know about C++":
you can have a declaration in a for-loop's *condition*
void use(unique_ptr<int>);
void drain(vector<unique_ptr<int>> v) {
for (int i = 0; auto el = move(v[i]); ++i)
use(move(el));
} // https://godbolt.org/z/ug2827
you can have a declaration in a for-loop's *condition*

void use(unique_ptr<int>);
void drain(vector<unique_ptr<int>> v) {
for (int i = 0; auto el = move(v[i]); ++i)
use(move(el));
} // https://godbolt.org/z/ug2827
Today's episode of "something I didn't know about C++":
template<class ...Ts>
void ellipsis(Ts......);
Template parameter pack, followed by C-style varargs that doesn't use the (optional!!!) comma.
template<class ...Ts>
void ellipsis(Ts......);
Template parameter pack, followed by C-style varargs that doesn't use the (optional!!!) comma.

Today's second episode of "something I didn't know about C++":
operator auto()
It's a thing. It has (inadvertent) meaning. h/t @AlisdairMered
operator auto()
It's a thing. It has (inadvertent) meaning. h/t @AlisdairMered
Today's episode of "something I didn't know about C":
union U { int : 0; };
Unions can contain bit-fields, including zero-sized anonymous bit-fields (which in a class makes the next bit-field start at an allocation unit's boundary, in a union… nothing).
union U { int : 0; };
Unions can contain bit-fields, including zero-sized anonymous bit-fields (which in a class makes the next bit-field start at an allocation unit's boundary, in a union… nothing).

Today's episode of "something I didn't know about C and C++":
int size() {
struct empty {};
return sizeof(struct empty);
}
This code returns 0 in C and 1 in C++, because empty structs have different size in both languages.
int size() {
struct empty {};
return sizeof(struct empty);
}
This code returns 0 in C and 1 in C++, because empty structs have different size in both languages.

Today's episode of "something I never imagined that I would see in real C++ code":
#pragma clang diagnostic error "-Weverything"
#pragma clang diagnostic error "-Weverything"

Today's episode of "something I didn't know about C++": falling off the end of a function try block does an implicit rethrow for constructors and destructors, but falls off the end of the function otherwise (which only main turns to an implicit `return 0;`).
h/t @MalwareMinigun
h/t @MalwareMinigun
Today's episode of "something I thought only browsers did and surely C++ compilers didn't": clang's __VERSION__ emulates GCC's and prints out as:
"4.2.1 Compatible Clang 9.0.0 (trunk 355887)"
Just like browser User-Agent string!
"4.2.1 Compatible Clang 9.0.0 (trunk 355887)"
Just like browser User-Agent string!
Today's episode of "something I didn't know about C (but not C++!)": you can define a type in offsetof and in casts! 
int o = offsetof(struct S { int a; }, a);
Macro expands to:
((size_t)&(((struct S { int a; } *)0)->a))
Watch those commas though! Likely fixed in C2x.

int o = offsetof(struct S { int a; }, a);
Macro expands to:
((size_t)&(((struct S { int a; } *)0)->a))
Watch those commas though! Likely fixed in C2x.
Today's episode of "something from C99 making its way into a weird C++ extension":
using abominable = void() const const const const const const const volatile volatile volatile volatile volatile &&; https://twitter.com/jfbastien/status/1113560327583453186
using abominable = void() const const const const const const const volatile volatile volatile volatile volatile &&; https://twitter.com/jfbastien/status/1113560327583453186
Today's episode of "something that endlessly amuses me about the C++ Standard":
"Stable names" for sections of the Standard include [over.ass] and [expr.ass].
Hehe, ISO-standard ass.
/cc @xexd
http://eel.is/c++draft/over.ass
http://eel.is/c++draft/expr.ass
"Stable names" for sections of the Standard include [over.ass] and [expr.ass].
Hehe, ISO-standard ass.
/cc @xexd
http://eel.is/c++draft/over.ass
http://eel.is/c++draft/expr.ass
Today's episode of "something I didn't know about C++ constexpr": case labels can be constant expressions.
Unfortunately, they can't be recursive
https://godbolt.org/z/Ye5Tid
Unfortunately, they can't be recursive

https://godbolt.org/z/Ye5Tid
Most interesting question: what's the order of evaluation of constexpr case labels?

Today's episode of "GCC tries to pull heroics in constexpr statement expressions".
Can you guess which value gets picked?
https://godbolt.org/z/NtlPkm
Can you guess which value gets picked?
https://godbolt.org/z/NtlPkm
Today's episode of "something I didn't know about C++ type traits":
is_constructible<T, Args...> is true if the type is constructible... as well as destructible! It's not true if the type is constructible but not destructible.
is_constructible<T, Args...> is true if the type is constructible... as well as destructible! It's not true if the type is constructible but not destructible.
Today's episode of "fun clang extension to C++": duplicate qualifiers without typedefs.
const const const
const int const
const const const CONSTANT_FORTRESS = 0;
const const const
const int const
const const const CONSTANT_FORTRESS = 0;
Today's episode of "something I didn't know about C++"
You can:
⁃ delete operator new
⁃ delete operator delete
*Cannot* new operator new.
struct S {
void* operator new(size_t) = delete;
void operator delete(void *) = delete;
void* operator new(size_t) = new; // No!
};
You can:
⁃ delete operator new
⁃ delete operator delete
*Cannot* new operator new.
struct S {
void* operator new(size_t) = delete;
void operator delete(void *) = delete;
void* operator new(size_t) = new; // No!
};
Today's episode of "something I didn't know about GNU C extensions":
There's a feature called "GNU case range extension"
enum enumeration { A, B, C, D, BORING };
int amazing(enumeration amaze) {
switch (amaze) {
case A ... D: return 42;
case BORING: return 0;
}
}
There's a feature called "GNU case range extension"
enum enumeration { A, B, C, D, BORING };
int amazing(enumeration amaze) {
switch (amaze) {
case A ... D: return 42;
case BORING: return 0;
}
}
Today's episode of "something I didn't know about C++ until C++17 took it away":
You've all heard of "POD" types?
There used to be "Plain Old Function" (POF!
) which defined what was callable from a signal handler.
Removed from C++17 by https://wg21.link/P0270
You've all heard of "POD" types?
There used to be "Plain Old Function" (POF!

Removed from C++17 by https://wg21.link/P0270
Today's episode of "something C++ used to disallow":
switch on floating-point values!
https://godbolt.org/z/mk2Q8e
@stephentyrone
switch on floating-point values!
https://godbolt.org/z/mk2Q8e
@stephentyrone

Today's episode of "fun C / C++ extension":
asm labels!
Specify the name to be used in assembler code for a function or variable: write asm keyword after the declarator. Don't like C++ mangling? No problem!
Unfortunately doesn't work with NTTPs
https://godbolt.org/z/nAFvoP
asm labels!
Specify the name to be used in assembler code for a function or variable: write asm keyword after the declarator. Don't like C++ mangling? No problem!
Unfortunately doesn't work with NTTPs

https://godbolt.org/z/nAFvoP
Today's episode of "fun things allowed by C++'s odd Unicode support":
using ಠ_ಠ = void;
Valid in major compilers: https://godbolt.org/z/uHTF3m
http://Seewg21.link/1949 for a cleanup!
h/t CSS for being more liberal: https://twitter.com/tabatkins/status/1099050056760487936
using ಠ_ಠ = void;
Valid in major compilers: https://godbolt.org/z/uHTF3m
http://Seewg21.link/1949 for a cleanup!
h/t CSS for being more liberal: https://twitter.com/tabatkins/status/1099050056760487936
Today's episode of "over-qualified for C++":
clang supports more than the usual "const" and "volatile" qualifiers.
It supports const, volatile, restrict, __unaligned, _Atomic, as well as 256 distinct address space.
Over-qualified indeed!
https://twitter.com/jfbastien/status/1017819242815631360
clang supports more than the usual "const" and "volatile" qualifiers.
It supports const, volatile, restrict, __unaligned, _Atomic, as well as 256 distinct address space.
Over-qualified indeed!

Today's "fun extension to C to make it look like C++": overloading! Who needs _Generic?
float __attribute__((overloadable)) tgsin(float x) { return sinf(x); }
double __attribute__((overloadable)) tgsin(double x) { return sin(x); }
https://clang.llvm.org/docs/AttributeReference.html#overloadable
float __attribute__((overloadable)) tgsin(float x) { return sinf(x); }
double __attribute__((overloadable)) tgsin(double x) { return sin(x); }
https://clang.llvm.org/docs/AttributeReference.html#overloadable