Live data from Hacker News

Some Obscure C Features

multun.net

71–80 of 147 posts

Re: Some Obscure C Features

#71

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…

The comma operatory leads to bad bad bugs (especially when mixed with misleading indentation) and if its use was punishable I wouldn't even be sad.

Re: Some Obscure C Features

#72
post #64
post #56

Earlier 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.

Perhaps they mean that operator overloading can break that equivalence.

Which is true, but I would argue an implementation that makes those operators behave differently is likely ill advised.

Re: Some Obscure C Features

#73

The 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…

I took the code sample of the article from a snippet intended to be as dirty as possible, and removed most madness out of it. But yeah you're right :D I just wanted to avoid adding one more item in that bullet list.

Re: Some Obscure C Features

#75

In 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…

I wish Javascript, etc. had hexadecimal floats. It’s annoying to worry about whether different implementations might parse your numbers differently, worrying about whether you need to write down 15 or 17 decimal digits, ...

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

#76
post #36

Earlier 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…

Sorry, in the first example I meant to write (adding a declaration and initialization for n):

    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

#77
post #27

Earlier 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.

C doesn't lack line comments. The obsolete 1989/1990/1995 version(s) of C did lack line comments.

Re: Some Obscure C Features

#78
post #41
post #26

> 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

I wasn't being ironic :)

Re: Some Obscure C Features

#79

The 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…

Another neat note IIRC is that array parameter sizes don't actually do anything, they just are there for semantic purposes and get treated as raw pointers.

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!
Post reply on HN