Live data from Hacker News

Some Obscure C Features

multun.net

91–100 of 147 posts

Re: Some Obscure C Features

#91
post #81

I was reading the source code for a NES assembler written in pre-C99 C, and there was an odd C feature used in it that I haven't really seen anywhere else. It was before C had built-in booleans and the author had defined their own, but true was: void * true_ptr = &true_ptr; true_ptr is a pointer to itself. So however many times you deference it: printf("%p\n", true_ptr); printf("%p\n", &true_ptr); printf("%p\n", *((v…

  cdecl> explain const void * const_pointer
  declare const_pointer as pointer to const void
  cdecl> explain void * const const_value
  declare const_value as const pointer to void
  cdecl>
The first must be the one that segfaults on write, IFF the compiler chooses to place it in the .text (as it should).

Re: Some Obscure C Features

#93

Earlier quoted context omitted.

Only if index and array have the types of same size. Because pointer arithmetic works in terms of object sizes, not in individual bytes.

foo[3] *(foo + 3) *(3 + foo) 3[foo] They all do the same thing.

Interesting! I assume because the literal is being coerced to be the size of the variable? After all:

    foo[3] == (void *)((usize)foo + (usize)(3 * sizeof(*foo)))

Re: Some Obscure C Features

#95

I found the most interesting one to be compile time trees. Does anyone have any good use cases for it?

I don't like to think of it as compile-time trees. It basically only allows you to construct complicated structures but doesn't allow you to examine them at compile time (that would require constexpr functions in C++; can't be done in C). It's honestly not a very impressive feature.

Re: Some Obscure C Features

#96

Most of these are due to the cruft added in C99 and later. Compile-time trees are possible without compound literals. More than twenty years ago, I made a hyper-linked help screen system a GUI app whose content was all statically declared C structures with pointers to each other. At file scope, you can make circular structures, thanks to tentative definitions, which can forward-declare the existence of a name, whose…

I haven't heard of "tentative definitions" before. Couldn't you just replace it with a regular declaration i.e.

    extern foo n1, n2;
Is there any benefit of tentative definitions over this?

Re: Some Obscure C Features

#97
No mention of trigraphs? They are one of my favourite obscure C language features that I've never used.

Excerpt from GCC man page:

  Trigraph:       ??(  ??)  ??  ??=  ??/  ??'  ??!  ??-
  Replacement:      [    ]    {    }    #    \    ^    |    ~
Missing backslash on your keyboard? No problem, just type ??/ instead.

Re: Some Obscure C Features

#98

Earlier quoted context omitted.

foo[3] *(foo + 3) *(3 + foo) 3[foo] They all do the same thing.

Interesting! I assume because the literal is being coerced to be the size of the variable? After all: foo[3] == (void *)((usize)foo + (usize)(3 * sizeof(*foo)))

Yeah, that's how pointer arithmetic works. Adding an int and a pointer assumes an array and gives you a pointer to the nth element in that direction (which had better exist, for your sake). char pointers can be used for byte offsets if a byte is a char on your platform (and it's been quite a while since that wasn't true).

You can also subtract two pointers into the same array and get the distance (in elements, not bytes). a[b - a] == b.

Re: Some Obscure C Features

#99

Earlier quoted context omitted.

Agreed, and I never made the connection that array[index] could be written as index[array] haha.

Only if index and array have the types of same size. Because pointer arithmetic works in terms of object sizes, not in individual bytes.

    typedef struct thing {
        char a;
        long long int nothing;
    } thing_t;

    #define P(x) printf("%s %c\n", #x, x)
    int main(int argc, char **argv)
    {
        thing_t array[1024];
        array[8].a = 'H';
        P(array[8].a);
        P((8[array]).a);
        P((*(8 + array)).a);
    }

Re: Some Obscure C Features

#100
post #83
post #81

I was reading the source code for a NES assembler written in pre-C99 C, and there was an odd C feature used in it that I haven't really seen anywhere else. It was before C had built-in booleans and the author had defined their own, but true was: void * true_ptr = &true_ptr; true_ptr is a pointer to itself. So however many times you deference it: printf("%p\n", true_ptr); printf("%p\n", &true_ptr); printf("%p\n", *((v…

I've used this feature to create constants that are unique IDs.

Wouldnt count macro work as well?
Post reply on HN