A 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…
Some Obscure C Features
71–80 of 147 posts
Re: Some Obscure C Features
#72Earlier quoted context omitted.
Not really. The way it's usually introduced is that you get the same "reference" both ways. The fact that it's literally equivalent, and especially that there's no pointer type requirement on the left-hand-side, with the consequence of allowing ridiculous code like 2[array], is pretty obscure. Even more so because the equivalence doesn't work that way in C++ -- in general, features of C that aren't available in C++ t…
>Even more so because the equivalence doesn't work that way in C++ What do you mean? As far as I remember, C++ is very similar in this respect when it comes to array and pointer types.
Which is true, but I would argue an implementation that makes those operators behave differently is likely ill advised.
Re: Some Obscure C Features
#73The article has examples of array parameters like int b[const 42][24][*] but you can get more fun with variably modified array parameters instead of just constants like 42. For example, double sum_a_weird_shaped_matrix(int n, double array[n][3*n]) { double total = 0; for (int x = 0; x has a variable and a more complicated expression in those positions. But those variably modified parameters can have arbitrary express…
Re: Some Obscure C Features
#74I found the most interesting one to be compile time trees. Does anyone have any good use cases for it?
Re: Some Obscure C Features
#75In numerical analysis, "Hexadecimal float with an exponent" is not an obscure feature, it's a really nice one! If you want to communicate to somebody an exact number that your program has output, you need to either tell them the decimal number to enough digits + the number of digits (i.e., "Float32(0.1)", which is distinct from "Float64(0.1)"), or you can tell them the same number in full precision in binary, in whic…
Often the numbers (e.g. coefficients of some degree 10 polynomial approximation of a special function) are not intended to be human-readable anyway. Such values were typically computed in binary in the first place, and the only place they ever need to be decimal is when written into the code, where they will be immediately reconverted to binary numbers for use.
Re: Some Obscure C Features
#76Earlier quoted context omitted.
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…
> If the operand is the name of an object [...] what does it mean to evaluate `n`? 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 iss…
int n = 42;
int vla[n];
sizeof vla;
not `sizeof n`). (It doesn't look like I can edit a comment.)Logically, evaluating the expression `vla` would mean reading the contents of the array object, which means reading the value of each of its elements. But there's clearly no need to do that to determine its size -- and if you actually did that, you'd have undefined behavior since the elements are uninitialized. (There are very few cases where the value of an array object is evaluated, since in most cases an array expression is implicitly converted to a pointer expression.)
In fact the declaration `int vla[n];` will cause the compiler to create an anonymous object, associated with the array type, initialized to `n` or `n * sizeof (int)`. Evaluating `sizeof vla` only requires reading that anonymous object, not reading the array object. The problem is that the standard doesn't express this clearly or correctly.
Re: Some Obscure C Features
#77Earlier quoted context omitted.
Line comments have been part of the C language for a long, long time (added in C99); so much so that, especially when discussing the subject on the internet, more and more often they predate some of the younger participants.
Personally, I didn't know that C lacked line comments until I ran into a project that compiled with -std=c89 -pedantic.
Re: Some Obscure C Features
#78> a[b] is literally equivalent to *(a + b). You can thus write some absolute madness such as 41[yourarray + 1]. Wow. This has to be the best C obscurity that I've ever seen.
Come on, that might not be obscure for a C ninja master like you, but I'm pretty sure many people had no idea ;-) Notice how the list is sorted from actually obscure to less interesting. I even took the time to write a pseudo disclaimer above this one :D
Re: Some Obscure C Features
#79The article has examples of array parameters like int b[const 42][24][*] but you can get more fun with variably modified array parameters instead of just constants like 42. For example, double sum_a_weird_shaped_matrix(int n, double array[n][3*n]) { double total = 0; for (int x = 0; x has a variable and a more complicated expression in those positions. But those variably modified parameters can have arbitrary express…
So if you do
void func(int x[10]);
You're free to call it like int k[5];
func(k);
And you won't get any warnings. Unsettling!Re: Some Obscure C Features
#80Are we calling these features, now?