Live data from Hacker News

Some Obscure C Features

multun.net

141–147 of 147 posts

Re: Some Obscure C Features

#141
post #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.

Related to trigraphs are the alternative logical operator keywords like `and` and `or`. I'm surprised people don't use them more often because they're nicer to read than && and ||. In C, you must #include but I think they're standard keywords. C++ code example on Godbolt: https://godbolt.org/z/ED6tXK https://en.cppreference.com/w/cpp/language/operator_alternat...

Hmmm... I would not prefer using "and" and "or" because that syntactic sugar obscures whether the bitwise or logical operations are intended. You get really used to reading && and || as "and" and "or" in your head after the first two decades of C programming : )

Re: Some Obscure C Features

#142
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…

Some early compilers such as THINK C for the Mac weren't very strict about typing when taking the address of an object. So for example you could do:

unsigned int x;

unsigned int * x_addr = &x;

unsigned int x_addr_addr = &(&x);

(or arbitrarily many levels of "address-of") and you'd just get the same address.

Re: Some Obscure C Features

#143
post #7

Although calling the preprocessor "functional" is being too pleasant. The C preprocessor was always a text substitution system, so macro as parameter is not that "obscure". Of course, I may have missed something subtle in the example. It's also not clear how to use that preprocessor example.

see http://conal.net/blog/posts/the-c-language-is-purely-functio... old but gold

>The C ADT is implemented simply as String (or char *, for you type theorists, using a notation from Kleene)

Still makes me laugh

Re: Some Obscure C Features

#144
post #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.

Related to trigraphs are the alternative logical operator keywords like `and` and `or`. I'm surprised people don't use them more often because they're nicer to read than && and ||. In C, you must #include but I think they're standard keywords. C++ code example on Godbolt: https://godbolt.org/z/ED6tXK https://en.cppreference.com/w/cpp/language/operator_alternat...

I can safely say that I have never #included iso646.h in my life.

Re: Some Obscure C Features

#145
post #108

Earlier quoted context omitted.

IIRC these are a legacy of BCPL

The story I heard was that the trigraphs were added during standardization because ISO 646, the international version of ASCII, did not require the characters [ \ ] { | }. Fun fact: ISO 646 is also the reason that IRC allows these characters in nicknames. IRC was created in Finland, and the Finnish national standard had placed the letters Ä Ö Å ä ö å at those code points. Edit: That doesn't explain the trigraphs for…

I had to use them once on a truly ancient amber screen serial terminal that lacked { and } on the keyboard. That was back in the 90s and the terminal was completely obsolete at the time but I needed to write a tiny hack program to solve an immediate problem. I remember only knowing about them in the first place from an odd compiler warning I'd seen on a different program.

Re: Some Obscure C Features

#146

Earlier quoted context omitted.

The wording in the C FAQ is that arrays “decay” into pointers when you pass them to functions. Which they explain as the reason why you can’t know the size of a passed array (at least in standard C.) The C FAQ is pretty old though, I’ve always wondered how much of that advice changed in C99/C11... from cursory googling things don’t seem to have changed much.

It's funny that K&R chose to have arrays "decay" to pointers, but to allow structs to be passed by value. Thus you can actually pass arrays by value if and only if you wrap them in a struct: struct foo { char a[5]; }; void f(struct foo x) { x.a[4] = '\0'; printf("%s", x.a); } int main(void) { struct foo x; memcpy(x.a, "too big", sizeof(x.a)); f(x) printf("%s", x.a); /* read past end of x, crash */ return 0; } I'm tha…

I figured that having arrays decay into pointers is one of those features that got grandfathered in because changing it would have broken the dozen or C programs that existed at the time. It's a real shame too because a working sizeof() for strings could have avoided a LOT of C exploits over the years.

Re: Some Obscure C Features

#147

No mention of the downto (-->) operator? int x = 10; while (x --> 0) { printf("%d ", x); }

That's just the decrement operator and inequality operator!

not inequality, rather the "greater-than" operator.

"!=" would be the inequality operator... :-)

Post reply on HN