Some Obscure C Features
51–60 of 147 posts
Re: Some Obscure C Features
#52 void (*foo)() = 0;
void (*bar)() = (void *)0;
void (*baz)() = (void *)(void *)0; // Error
Can you guess why compilers reject the last line?Re: Some Obscure C Features
#53For instance, the next line has a valid C construct:
return a, b, c;
This is particularly useful for setting variable when retuning after an error. if (ret = io(x))
return errno = 10, -1;
The possibilities are endless. Another example: if (x = 1, y = 2, x
But the comma operator really shines when used in conjunction with macros.Re: Some Obscure C Features
#54Does anyone have any good use cases for it?
Re: Some Obscure C Features
#55All craziness but then: >a[b] is literally equivalent to *(a + b). Is this obscure? I thought that's pretty much the first thing you learn about arrays in C? It's pointers, all the way down.
Re: Some Obscure C Features
#56All craziness but then: >a[b] is literally equivalent to *(a + b). Is this obscure? I thought that's pretty much the first thing you learn about arrays in C? It's pointers, all the way down.
Re: Some Obscure C Features
#57sizeof actually doesn't evaluate its expression for side effects most of the time; only if the operand is a variable-length array is it evaluated.
And it's not even entirely clear what that means. The standard says: "If the type of the operand is a variable length array type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an integer constant." But what does it mean to evaluate the operand? If the operand is the name of an object: int vla[n]; sizeof n; what does it mean to evaluate `n`? Logically, evaluating it should access…
When you say "n", syntactically, you have a primary expression that is an identifier. So you follow the rules for evaluating an identifier, which will produce the value. C doesn't describe it very well, but the value of the expression is the value of the object. In terms of how it is implemented in actual compilers, this would mean issuing a load of the memory location, which is dead unless `n` is a volatile variable.
Re: Some Obscure C Features
#58A more obscure feature is the uncommon usage of comma operator. We often use the comma operator in variable declaration and in for loops. But it can also be used in any expression. For instance, the next line has a valid C construct: return a, b, c; This is particularly useful for setting variable when retuning after an error. if (ret = io(x)) return errno = 10, -1; The possibilities are endless. Another example: if…
Re: Some Obscure C Features
#59A more obscure feature is the uncommon usage of comma operator. We often use the comma operator in variable declaration and in for loops. But it can also be used in any expression. For instance, the next line has a valid C construct: return a, b, c; This is particularly useful for setting variable when retuning after an error. if (ret = io(x)) return errno = 10, -1; The possibilities are endless. Another example: if…
The comma operator isn’t very obscure at all. Even JS has it.
Re: Some Obscure C Features
#60A little off-topic but here is a cool piece of code about a special case in C: void (*foo)() = 0; void (*bar)() = (void *)0; void (*baz)() = (void *)(void *)0; // Error Can you guess why compilers reject the last line?