Live data from Hacker News

Lesser known tricks, quirks and features of C

blog.joren.ga

91–100 of 189 posts

Re: Lesser known tricks, quirks and features of C

#91
post #70

I'm a bit better at English than c, and in the spirit of language peculiarities, this jumped out at me: > It's possible, because C cares less than more about whitespace Idiomatically we'd say 'couldn't care less'. I guess we should be glad it wasn't the diabolical and illogical 'could care less'

c does care about whitespace - compare: int x; with: intx;

Try removing spaces here:

  *z = *x / *y;
Or here:

  address = mask & &object;
Or here:

  a = b - --c;

Re: Lesser known tricks, quirks and features of C

#92
post #75

Earlier quoted context omitted.

Why are these not compiler errors by default? Opting in to such important safety features seems like broken design.

One reason is locale-dependent format strings which are loaded from resource files. Also, in personal projects, I almost always used custom wrapper functions for printf/fprintf/sprintf for various reasons, so that default wouldn’t be of much use, unless maybe I could enable it for the custom functions.

> One reason is locale-dependent format strings which are loaded from resource files.

Aren't those usually resolved to string literals by preprocessor such that the compiler still could emit a warning?

Re: Lesser known tricks, quirks and features of C

#94
post #38

Very nice collection. My favorite C feature is actually a gcc/clang feature : the __INCLUDE_LEVEL__ predefined macro. It made me code&maintain my C projects exactly twice as fast as before because file count dropped to half : https://github.com/milgra/headerlessc .

How do you handle third party headers?

Re: Lesser known tricks, quirks and features of C

#96
post #75

Earlier quoted context omitted.

Why are these not compiler errors by default? Opting in to such important safety features seems like broken design.

One reason is locale-dependent format strings which are loaded from resource files. Also, in personal projects, I almost always used custom wrapper functions for printf/fprintf/sprintf for various reasons, so that default wouldn’t be of much use, unless maybe I could enable it for the custom functions.

You can with __attribute__((format(printf, 1, 2))) See: https://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/Function-Attrib...

Re: Lesser known tricks, quirks and features of C

#98
post #38

Very nice collection. My favorite C feature is actually a gcc/clang feature : the __INCLUDE_LEVEL__ predefined macro. It made me code&maintain my C projects exactly twice as fast as before because file count dropped to half : https://github.com/milgra/headerlessc .

This is great!

Re: Lesser known tricks, quirks and features of C

#99
post #75

Earlier quoted context omitted.

One reason is locale-dependent format strings which are loaded from resource files. Also, in personal projects, I almost always used custom wrapper functions for printf/fprintf/sprintf for various reasons, so that default wouldn’t be of much use, unless maybe I could enable it for the custom functions.

> One reason is locale-dependent format strings which are loaded from resource files. Aren't those usually resolved to string literals by preprocessor such that the compiler still could emit a warning?

That might be possible if the "resource file" was processed at compile time. I've never seen a C toolchain that did it that way, though - I've only seen them read in at runtime. And at that point, the preprocessor can't save you.

Re: Lesser known tricks, quirks and features of C

#100
post #35
post #6

Fun fact about %n: Mazda cars used to have a bug where they used printf(str) instead of printf("%s", str) and their media system would crash if you tried to play the "99% Invisible" podcast in them. All because the "% In" was parsed as a "%n" with some extra modifiers. https://99percentinvisible.org/episode/the-roman-mars-mazda-...

"format not a string literal" is one warning I always upgrade to an error. Dear reader: you should do this, too!

I don't like a lot of things in C++, but one thing worth praising in particular is std::format

std::format specifically only works for constant† format strings. Not because they can't make it work with a dynamic format, std::vformat is exactly that, but most of the time you don't want and shouldn't use a dynamic format and the choice to refuse dynamic formats in std::format means fewer people are going to end up shooting themselves in the foot.

Because it requires constant formats, std::format also gets to guarantee compile time errors. Too many or not enough arguments? Program won't build. Wrong types? Program won't build. This shifts some nasty errors hard left.

† Not necessarily a literal, any constant expression, so it just needs to have some concrete value when it's compiled.

Post reply on HN