News for hackers. Stuff that matters.
Re:Few lesser known tricks, quirks and features of C by gallier2 on Sunday February 19, 2023 @12:29PM (#34859699)
Cool. Two of the tricks shown are from my contribution in stackoverflow.
Re:Few lesser known tricks, quirks and features of C by vocram on Sunday February 19, 2023 @12:37PM (#34859776)
Yet another proof that C is simple but not easy.
Re:Few lesser known tricks, quirks and features of C by SAI_Peregrinus on Sunday February 19, 2023 @01:44PM (#34860483)
The simplest languages tend to be the most difficult. Brainfuck, Binary Lambda Calculus, Unlambda, and other "Turing tarpits" are all extremely difficult to use for anything even mildly complex.
Re:Few lesser known tricks, quirks and features of C by mtlmtlmtlmtl on Sunday February 19, 2023 @02:09PM (#34860731)
I always felt like unlambda and other SKI calculus esque esolangs(iota comes to mind) could have some kinda strange use case in some kind of generalised genetic programming. It should be possible to create a binary notation for SKI calculus where arbitrary bitstrings will be valid, and so one could randomly mutate and recombine arbitrary programs. Though I've never delved deeper into genetic algorithms and evolutionary programming, my sense is that genetic algorithms tend to be restricted to parameterised algorithms where the "genes" determine the various parameters. Which can be great for optimisation problems.

It's one of those weird ideas I've had kicking about for years but never did anything about, and yet I keep coming back to it.

Re:Few lesser known tricks, quirks and features of C by alcover on Sunday February 19, 2023 @05:31PM (#34862542)
This must be an avenue for very exciting explorations. I'm quite ignorant about this stuff but have some questions :

  > It should be possible to create a binary notation for SKI calculus where arbitrary bitstrings will be valid
What if it's not ? How will your genetic petri dish spot and eliminate invalid programs ?

  > one could randomly mutate and recombine arbitrary programs
What if non-halting programs get generated ?

In this vein I've seen magnificent images of 1D cellular automatons that use the surrounding pattern to decide on the local rule for next gen.

Re:Few lesser known tricks, quirks and features of C by mtlmtlmtlmtl on Sunday February 19, 2023 @05:55PM (#34862738)
I assume that an invalid program would not compile/parse, and so would die and fail to reproduce. The issue is more that if the space of invalid programs is too large compared to the space of valid ones, generating valid offspring by combining two programs would be too rare and the population would die off.

Though if the space is small enough I imagine you could get past that. It's a bit of a gnarly point, hard to tell how this would turn out without trying I suppose.

As for the halting problem there's of course no clever solution there other than limiting CPU time. So I guess pick a reasonable limit that makes sense for whatever you're trying to do.

Re:Few lesser known tricks, quirks and features of C by elcritch on Sunday February 19, 2023 @01:59PM (#34860629)
Forth. It’s easy for a small cute script. But quickly becomes a PITA.
Re:Few lesser known tricks, quirks and features of C by gatane on Sunday February 19, 2023 @11:34PM (#34864933)
Stack machines look cool until you realize you could save all the stack mumbling by using registers. At this point, you could try to make a full VM instead.
Re:Few lesser known tricks, quirks and features of C by dantle on Sunday February 19, 2023 @12:44PM (#34859873)
Nice article. Saw a few things I wish I'd known about.

1. %n in printf would be handy when writing CLIs dealing w/ multiple lines or precise counts of backspaces.

2. Using enums as a form of static_assert() is a great idea (triggering a div by zero compiler error).

Re:Few lesser known tricks, quirks and features of C by torstenvl on Sunday February 19, 2023 @01:15PM (#34860216)
%n is an extremely poor fit for CLI manipulation or tokenization for backspacing.

%n is for bytes, not user-perceived characters.

Re:Few lesser known tricks, quirks and features of C by jcelerier on Sunday February 19, 2023 @02:23PM (#34860872)
using enums as a form of static_assert is very bad when C nowadays literally has static_assert (_Static_assert: https://gcc.godbolt.org/z/bfv6rKdKM)
Re:Few lesser known tricks, quirks and features of C by tom_ on Sunday February 19, 2023 @03:17PM (#34861387)
The enum idea is interesting. I've previously used an extern with a conditional size of either 1 (valid) or -1 (invalid). This requires no additional boilerplate, and is #define-able into a static assert when built with a recent enough compiler. Something like this, from memory:

    #define STATIC_ASSERT(COND) extern char static_assert_cond_[(COND)?1:-1] /* C99 or earlier */
    #define STATIC_ASSERT(COND) _Static_assert(COND) /* C11 or later */
As both are declarations, I don't think you'll end up in a situation where one is valid and the other isn't - but I could be wrong, and I suspect it would rarely matter in practice anyway.
Re:Few lesser known tricks, quirks and features of C by Miserlou57 on Sunday February 19, 2023 @12:45PM (#34859897)
“Quirks and features”
Re:Few lesser known tricks, quirks and features of C by aranchelk on Sunday February 19, 2023 @01:09PM (#34860151)
Where’s the DougScore?
Re:Few lesser known tricks, quirks and features of C by ufo on Sunday February 19, 2023 @12:48PM (#34859925)
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-...

Re:Few lesser known tricks, quirks and features of C by rerdavies on Sunday February 19, 2023 @01:53PM (#34860577)
Fun fact about %n:

The %n functionality also makes printf accidentally Turing-complete even with a well-formed set of arguments. A game of tic-tac-toe written in the format string is a winner of the 27th IOCCC.

- sez wiki.

A not so fun fact:

Because the %n format is inherently insecure, it's disabled by default.

- MSVC reference.

Re:Few lesser known tricks, quirks and features of C by charcircuit on Sunday February 19, 2023 @11:18PM (#34864844)
>The %n functionality also makes printf accidentally Turing-complete

No it doesn't. Printf has no way to loop so it's not Turing complete. Even if you did what the IOCCC entry did it still wouldn't be Turing complete as it would not have an infinite memory.

Re:Few lesser known tricks, quirks and features of C by webstrand on Monday February 20, 2023 @12:07AM (#34865112)
Nothing real is "Turing complete" if it requires infinite memory. That's a property only abstract machines can have. In common parlance, something is Turing complete if it can compute arbitrary programs that can be computed with M bits of memory, where M is arbitrary but finite.
Re:Few lesser known tricks, quirks and features of C by charcircuit on Monday February 20, 2023 @03:20AM (#34866167)
So in common parlance finite state automata are Turing complete? That definition doesn't make any sense.
Re:Few lesser known tricks, quirks and features of C by foldr on Monday February 20, 2023 @06:00AM (#34867036)
I'd say they're Turing complete (in common parlance) if they can reasonably viewed as a Turing-complete system that's been hobbled with an arbitrary memory limitation. FSAs generally can't be viewed this way as you can't just "add more memory" to an FSA. By way of contrast, consider a pushdown automaton with two stacks. While any physically real implementation of such a device will necessarily have some kind of limit on the size of the stacks, you can easily see how the device would behave if this limit were somehow removed.

It's definitely a bit fuzzy. I'm sure lots of philosophy papers have been written on when exactly it is or isn't appropriate to consider a finite computational system as a finite approximation to a Turing-complete system. In realistic everyday cases, however, it's usually clear enough what should and shouldn't count as such.

Re:Few lesser known tricks, quirks and features of C by charcircuit on Monday February 20, 2023 @07:14AM (#34867392)
>as you can't just "add more memory" to an FSA.

Adding another state to a FSA adds more memory.

There is no difference between a hobbled Turing machine and a FSA. Turing machines aren't a useful concept in the real world and that is okay.

Re:Few lesser known tricks, quirks and features of C by foldr on Monday February 20, 2023 @07:37AM (#34867529)
>Adding another state to a FSA adds more memory.

Yes, but it also changes the state transition logic. You can't just 'add 100 more states' to an FSA in the same way that you can 'add 100 more stack slots' to a bounded pushdown automaton.

As I said previously, these are somewhat fuzzy distinctions, and I'm not saying that they're easy to make mathematically precise. They do however seem clear enough in most cases of practical interest. There are many real-world computing systems that would be Turing-complete if they had unbounded memory. There are others that are not Turing-complete for more fundamental reasons than memory limitations.

Re:Few lesser known tricks, quirks and features of C by mjburgess on Monday February 20, 2023 @06:06AM (#34867062)
Re:Few lesser known tricks, quirks and features of C by Sharlin on Monday February 20, 2023 @06:07AM (#34867066)
Strictly speaking there are essentially no programming languages that are even theoretically Turing-complete because they can only address a bounded amount of memory. For example, in C `sizeof(void*)` must be a well-defined, finite integer. But that definition is not useful in practical use.
Re:Few lesser known tricks, quirks and features of C by charcircuit on Monday February 20, 2023 @07:13AM (#34867387)
There are plenty of Turing complete languages. For example JavaScript is Turing complete.
Re:Few lesser known tricks, quirks and features of C by Sharlin on Monday February 20, 2023 @01:20PM (#34870972)
Even if that was true, any definition of Turing completeness that includes JavaScript and excludes C is worse than useless in practice. It's useless for communication, it's useless for education, it's useless for reasoning about capabilities. There's simply no place for such a definition in a civilized society.
Re:Few lesser known tricks, quirks and features of C by charcircuit on Monday February 20, 2023 @03:23PM (#34872428)
Turing machines themselves are a useless concept in our society. Since C is lower level and tied more to the physical hardware it makes sense that it is not Turing complete because Turing machines are not applicable to the real world. Computers do not work anything like an infinite tape. I've never seen a practical program have to implement a Turing machine.
Re:Few lesser known tricks, quirks and features of C by Joker_vD on Monday February 20, 2023 @06:31AM (#34867162)
Well, I'm pretty sure all existing digital computers are finite state automata, so they are not, strictly speaking, Turing complete. But that doesn't make any sense.
Re:Few lesser known tricks, quirks and features of C by billpg on Monday February 20, 2023 @09:12AM (#34868212)
My laptop with its finite RAM isn't Turing Complete? Wow.
Re:Few lesser known tricks, quirks and features of C by tom_ on Sunday February 19, 2023 @03:07PM (#34861305)
"format not a string literal" is one warning I always upgrade to an error. Dear reader: you should do this, too!
Re:Few lesser known tricks, quirks and features of C by wrigby on Sunday February 19, 2023 @03:14PM (#34861351)
Thanks! This prompted me to look up the flag to enable this. For GCC it’s:

  -Werror=format-security
Re:Few lesser known tricks, quirks and features of C by fay59 on Monday February 20, 2023 @10:47AM (#34869210)
The flag is -Wformat-nonliteral or -Wformat=2. -Wformat-security only includes a weaker variant that will warn if you pass a variable and no arguments to printf.
Re:Few lesser known tricks, quirks and features of C by Gigachad on Sunday February 19, 2023 @05:20PM (#34862455)
Why are these not compiler errors by default? Opting in to such important safety features seems like broken design.
Re:Few lesser known tricks, quirks and features of C by tedunangst on Sunday February 19, 2023 @06:09PM (#34862846)
There's more than one compiler.
Re:Few lesser known tricks, quirks and features of C by Conscat on Sunday February 19, 2023 @06:18PM (#34862924)
How could that really work? printf is a library function, not an intrinsic. A function named printf can do anything your heart desires.
Re:Few lesser known tricks, quirks and features of C by ladberg on Sunday February 19, 2023 @06:56PM (#34863206)
Depends on the compiler, but you'd mark the printf function with something like: __attribute__((format(printf, 1, 2)))
Re:Few lesser known tricks, quirks and features of C by account42 on Wednesday February 22, 2023 @10:29AM (#34897087)
It's a standard library function meaning the compiler can assume that it follows the standard. Specifically for GCC [0]:

> The ISO C90 functions abort, abs, acos, asin, atan2, atan, calloc, ceil, cosh, cos, exit, exp, fabs, floor, fmod, fprintf, fputs, free, frexp, fscanf, isalnum, isalpha, iscntrl, isdigit, isgraph, islower, isprint, ispunct, isspace, isupper, isxdigit, tolower, toupper, labs, ldexp, log10, log, malloc, memchr, memcmp, memcpy, memset, modf, pow, printf, putchar, puts, realloc, scanf, sinh, sin, snprintf, sprintf, sqrt, sscanf, strcat, strchr, strcmp, strcpy, strcspn, strlen, strncat, strncmp, strncpy, strpbrk, strrchr, strspn, strstr, tanh, tan, vfprintf, vprintf and vsprintf are all recognized as built-in functions unless -fno-builtin is specified (or -fno-builtin-function is specified for an individual function).

Builtin here doesn't mean that GCC won't ever emit calls to library functions, only that it reserves not to and allows itselfs to make assumptions about how the functions work, including diagnosing misuse.

The library functions themselves might also be marked with __attribute__(format(...)) as the sibling comment notes but that is not necessarily required for GCC to check the format strings.

[0] https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html

Re:Few lesser known tricks, quirks and features of C by layer8 on Sunday February 19, 2023 @06:28PM (#34862987)
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.

Re:Few lesser known tricks, quirks and features of C by garaetjjte on Sunday February 19, 2023 @06:52PM (#34863178)
At least for GCC/clang, you can mark your functions with special __attribute__ format.

For loading translated strings, I'm missing some library function to verify whether two format strings are argument-compatible.

Re:Few lesser known tricks, quirks and features of C by wyldfire on Sunday February 19, 2023 @07:30PM (#34863474)
> 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:Few lesser known tricks, quirks and features of C by AnimalMuppet on Sunday February 19, 2023 @08:13PM (#34863794)
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:Few lesser known tricks, quirks and features of C by layer8 on Monday February 20, 2023 @11:10AM (#34869452)
Since the locale is only determined at runtime, and might even change at runtime, the format strings are usually dynamically loaded from text files, and are not in the form of string literals seen by the compiler.
Re:Few lesser known tricks, quirks and features of C by panzi on Sunday February 19, 2023 @07:44PM (#34863573)
You can with __attribute__((format(printf, 1, 2))) See: https://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/Function-Attrib...
Re:Few lesser known tricks, quirks and features of C by tom_ on Monday February 20, 2023 @03:32AM (#34866250)
I've never seen locale-dependent format strings work well. The translators will change the formatting codes, and you can't change the order of the formatted arguments. You are much better off with some other mechanism for this.

(I have no recommendations. When I've seen this stuff done properly, on the occasions I've managed not to avoid doing it, it's always been using some in-house system.)

Re:Few lesser known tricks, quirks and features of C by dezgeg on Monday February 20, 2023 @03:45AM (#34866322)
> you can't change the order of the formatted arguments.

You can with the $ syntax. Never seen it used though. Maybe it isn't very portable.

Re:Few lesser known tricks, quirks and features of C by skissane on Monday February 20, 2023 @05:28AM (#34866875)
It is specified by POSIX, but not by ISO C (or C++). So most Unix(-like) systems support it. But the printf in Microsoft's C runtime doesn't. However, Microsoft does define an alternative printf function which does, printf_p, so `#define printf printf_p` will get past that.

I think the real reason you rarely see it, is it is only used with internationalisation–the idea being if you translate the format string, the translator may need to reorder the parameters for a natural translation, given differences in word order in different languages. However, a lot of software isn't internationalised, or if it is, the internationalisation is in end-user facing text, which nowadays usually ends up in a GUI or web UI, so printf has less to do with it. And the kind of lower-level tools/components for which people still often use C are less likely to be internationalised, since they are targeted at a technical audience who are expected to be able to read some level of English.

Re:Few lesser known tricks, quirks and features of C by tom_ on Monday February 20, 2023 @03:35PM (#34872582)
printf_p is pretty neat, thanks for the pointer. But I would bet that you will still find at least one %d gets turned into a %s.

I like printf format strings, but as a way of handling localizable strings I don't think they are the best.

Re:Few lesser known tricks, quirks and features of C by skissane on Monday February 20, 2023 @06:39PM (#34874398)
You are 100% correct. printf, even with the argument numbering feature, is insufficient for high quality internationalisation.

A good example of this is pluralisation. We've all done things like:

    printf("%d file(s) copied\n", count);
which is acceptable but kind of ugly. Some people want to make it nicer:

    printf("%d file%s copied\n", count, count != 1 ? "s" : "");
Which is fine for English, but doesn't work at all for other languages. The problem is not just that the plural ending is something other than `s` – if it was just that, it wouldn't be too hard. The problem is that the the `count != 1` bit only works for English. For example, while 0 is plural in English, in French it is singular. Many other languages are much more complex. The GNU gettext manual has a chapter which goes into this in great detail – https://www.gnu.org/software/gettext/manual/html_node/Plural...

printf() has zero hope of coping with this complexity. gettext() provides a special function to handle this, ngettext(), which is passed the number as a separate argument, so it can select which plural form to use. And then the translated message files contain a header defining how many plural forms that language has, and the rules to choose which one to use. And for some languages it is crazy complex. Arabic is the most extreme, for which the manual gives this plural rule:

    Plural-Forms: nplurals=6; \
        plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 \
        : n%100>=11 ? 4 : 5;
Re:Few lesser known tricks, quirks and features of C by fay59 on Monday February 20, 2023 @10:48AM (#34869216)
The former is ideally resolved with attribute((format_arg)), the latter with attribute((format)).
Re:Few lesser known tricks, quirks and features of C by plq on Sunday February 26, 2023 @06:03AM (#34944643)
In principle, they are not enabled by default because a C compiler must be able to compile standard C by default.

One practical reason I can think of is because not everyone compiles their own code.

You must most definitely look for and enable such flags as they become available in your own projects. (eg I was rooting for -Wlifetime but it did not land for various reasons)

But when you compile other people's code, your breaking your local build doesn't help anyone. Best you can do is to submit a bug report, which may or may not be ignored.

Re:Few lesser known tricks, quirks and features of C by tialaramex on Sunday February 19, 2023 @09:14PM (#34864215)
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.

Re:Few lesser known tricks, quirks and features of C by planede on Monday February 20, 2023 @04:42AM (#34866617)
Nice, I didn't know about https://wg21.link/P2216 .
[dead]
Re:Few lesser known tricks, quirks and features of C by saagarjha on Tuesday February 21, 2023 @07:49AM (#34880522)
%@.
Re:Few lesser known tricks, quirks and features of C by GolangProject on Wednesday February 22, 2023 @11:10AM (#34897789)
This is one of those annoying little problems that is easily picked up by the vet command (https://pkg.go.dev/cmd/vet) when writing Go code. There are, of course, many linters that do the same thing in C, but it's nice to have an authoritative one built in as part of the official Go toolchain, so everyone's code undergoes the same basic checks.
Re:Few lesser known tricks, quirks and features of C by foobiekr on Sunday February 19, 2023 @12:55PM (#34859996)
Most of these are pretty familiar if old enough but this is a wonderful list.

I didn’t know C23 was getting rid of trigraphs. That’s probably a good thing and easy to clean up if needed.

Re:Few lesser known tricks, quirks and features of C by int_19h on Sunday February 19, 2023 @04:36PM (#34862104)
The bit about "register" is old enough that I don't think it's meaningful anymore.

The stock verbiage about how modern compilers ignore "register" because they can do better but it may be useful on simpler ones, has been around in this exact form 20 years ago already. And one curious thing is that even back then, such statements would never list specific compilers where "register" still did something useful.

So far as I can tell, "register" was in actual use back when many C compilers were still single-pass, or at least didn't have a full-fledged AST, and thus their ability to do things like escape analysis was limited. With that in mind, "register" was basically a promise to such a compiler to not take the address of a local in the function body (this is the only standard way in which it affects C semantics!). But we haven't had such compilers for a very long time now, even when targeting embedded - the compilers themselves run on full-power hardware, so there's no reason for them to take shortcuts.

Re:Few lesser known tricks, quirks and features of C by camel-cdr on Sunday February 19, 2023 @05:56PM (#34862747)
I think register is closer to const, as in: it's a hint to the programmer not the compiler.

So if you want to make absolutely sure that a variable can always be in a register then you should consider adding the register specifier to stop other programmers from taking the address of that variable.

Re:Few lesser known tricks, quirks and features of C by moonchild on Sunday February 19, 2023 @06:25PM (#34862977)
Taking the address of a variable does not prevent the compiler from putting it in a register. Indeed, it can be convenient to have small utility functions which are always inlined, which take pointers to their results; this should not and does not prevent those results from staying in registers.
Re:Few lesser known tricks, quirks and features of C by saagarjha on Tuesday February 21, 2023 @07:53AM (#34880553)
Correct, but preventing people from taking the address of things actually makes a difference for certain constructs in the standard (fore example, when it comes to trap representations).
Re:Few lesser known tricks, quirks and features of C by int_19h on Monday February 20, 2023 @01:31AM (#34865575)
Yes, you can treat "register" as a hint "no pointer to this ever exists anywhere in this program" for the reader. But you can only use it for locals, and that kind of metadata would be most useful (to other devs) on globals and fields - they can already see if a local ever has & applied to it or not.

OTOH I didn't recall this bit, but apparently you can also apply it to arrays. Which keeps them indexable, but you can't take addresses of elements nor of the whole array anymore. Now I'm not sure if the compiler can do anything useful with this, but it would allow it to play with alignment and padding - e.g. storing "register bool x[10]" as 10 words rather than 10 bytes. Is there any architecture on which that would be beneficial, though?

Re:Few lesser known tricks, quirks and features of C by taviso on Sunday February 19, 2023 @06:41PM (#34863081)
It's still useful on non-simple compilers when mixing inline assembly and c, for example `register __m128 foo asm("ymm7")`.

I realize that's a gnu extension - but it's super useful!

Re:Few lesser known tricks, quirks and features of C by int_19h on Monday February 20, 2023 @01:22AM (#34865519)
It definitely is, but it's that ability to bind it to a specific register that makes all the difference - and, of course, that can't be portable C (although it would be nice if we had non-portable supersets per arch, so that e.g. all x86 compilers would do this the same way).
Re:Few lesser known tricks, quirks and features of C by kevin_thibedeau on Sunday February 19, 2023 @12:59PM (#34860044)
> The 0 width field tells that the following bit fields should be set on the next atomic entity (char).

This isn't correct since int can't be less than 16-bits. Fields are placed on the nearest natural alignment for the target platform, which might not support unaligned access.

Re:Few lesser known tricks, quirks and features of C by titzer on Sunday February 19, 2023 @01:40PM (#34860455)
C is fundamentally confused, because it offers (near) machine-level specifications but then leaves just enough wiggle room for compilers to "optimize" (through alignment and such) while ruining the precision of a specification. You end up not getting exactly what you want at the machine level. It's infuriating.

The bitfield stuff in C would be fantastic if it weren't fundamentally broken. E.g. some Microsoft compilers in the past interpreted bit fields as signed...always. In V8 we had a work around with templates to avoid bitfields altogether. Fail.

Re:Few lesser known tricks, quirks and features of C by HybridCurve on Sunday February 19, 2023 @06:02PM (#34862805)
I think the problem with this is the C compiler has to find a solution which work with all the architectures it is expected to support. It order to achieve this, it must generalize in some areas and have flexibility in others. C programmers are required to be familiar with both the specifics of the architectures they are building for and the idiosyncrasies of their complier. I always assumed most other compiled languages were like this since I started with C and moved to x86 assembly from there. However, the more I read about people disliking C for this reason, the more I believe this may not be the case.

> The bitfield stuff in C would be fantastic if it weren't fundamentally broken

Bitfields in C can be manageable. Each compiler has it's own set of rules for how it prefers to arrange and pack them. Despite them not always being intuitive, I use them regularly since they are so succinct. If you are concerned about faithful and predictable ordering you generally just have a test program which uses known values to verify your layout as part of your build configuration or test battery.

> ... some Microsoft compilers ...

I've used many C compilers but I have always avoided microsoft ones, going so far to carry a floppy disc with my own when working in the lab at school.

Re:Few lesser known tricks, quirks and features of C by titzer on Sunday February 19, 2023 @06:35PM (#34863031)
> Bitfields in C can be manageable.

For the use case of specifying a more efficient representation of a fiction confined to the program, then no harm, no foul. But the use case of specifying a hardware- or network- or ABI-specified data layout, then you need those bits in exactly the right spot, and the compiler should have no freedom whatsoever. (I'm thinking of the case of network protocol packets and hardware memory-mapped registers).

Re:Few lesser known tricks, quirks and features of C by pantalaimon on Monday February 20, 2023 @01:09AM (#34865452)
I’ve seen them used for hardware register access a lot. But there were usually a separate set of header files for when you are not using GCC/Clang - I didn’t look at those
Re:Few lesser known tricks, quirks and features of C by HybridCurve on Monday February 20, 2023 @04:43AM (#34866625)
This shouldn't be an issue unless you are attempting to have the bit field span across your type boundary. Bit fields by definition are constituents of a type. It doesn't restrict you from putting the bits where you want them but how you accomplish that. In this case, you'd either have to split the value across the boundary into two fields or use a combination of struct/unions to create an aliased bit field using a misaligned type (architecture permitting of course). You either sacrifice some convenience (split value) or some readability (union) but it is still reasonable.

The compiler itself is not taking a liberal approach to bit field management, it is only working within the restriction of the type (I am speaking for GCC here, I can't vouch for others). But if you think of them as an interface to store packed binary data freely without limitations I can understand why they seem frustrating. They are much more intuitive when you consider them as being restricted to the type.

Re:Few lesser known tricks, quirks and features of C by rerdavies on Sunday February 19, 2023 @01:44PM (#34860496)
int isn't a bitfield.
Re:Few lesser known tricks, quirks and features of C by Jorengarenar on Sunday February 19, 2023 @02:05PM (#34860683)
I think I'll use other example. Thanks!
Re:Few lesser known tricks, quirks and features of C by kevin_thibedeau on Sunday February 19, 2023 @05:38PM (#34862602)
You can just expand your example to use 16-bit values or switch to uint8_t. Bitfields with signed integers are also a minefield so it's best to never attempt it.
Re:Few lesser known tricks, quirks and features of C by suprjami on Monday February 20, 2023 @04:16AM (#34866460)
The entire placement of bitfields is implementation defined.

So yeah, the placement in memory might be `xxxxx000 00000000 yyyyyyy0` but it could also be `yyyyyyy0 00000000 xxxxx000` or `yyyyyyy0 00000000 00000000 xxxxx000` or anything else.

Bitfields are very misunderstood and really only safe to treat as an ADT with access through their named API, not their bit placement ABI. People misuse them a lot.

Re:Few lesser known tricks, quirks and features of C by ikran03 on Sunday February 19, 2023 @01:03PM (#34860084)
Too young to know about anything in there, but these look so interesting. Can't wait to show off '%n' in my next uni project
Re:Few lesser known tricks, quirks and features of C by nstbayless on Sunday February 19, 2023 @01:08PM (#34860146)
Here's another one. Handy "syntax" that makes it possible to iterate an unsigned type from N-1 to 0. (Normally this is tricky.)

for (unsigned int i = N; i --> 0;) printf("%d\n", i);

This --> construction also works in JavaScript and so on.

Re:Few lesser known tricks, quirks and features of C by titzer on Sunday February 19, 2023 @01:35PM (#34860411)
AFAICT this would parse as "(i--) > 0", there's no "-->" operator.
Re:Few lesser known tricks, quirks and features of C by texaslonghorn5 on Sunday February 19, 2023 @02:23PM (#34860875)
Re:Few lesser known tricks, quirks and features of C by Jorengarenar on Sunday February 19, 2023 @02:33PM (#34860971)
I was hesitant to put it on the list, but fine, you convinced me
Re:Few lesser known tricks, quirks and features of C by stonegray on Sunday February 19, 2023 @02:39PM (#34861031)
If you're gonna test the i--, shouldn't it fall through on zero anyway?

    for (unsigned int i = N; i--;){}

    unsigned int i = N;
    while(i--){ ... }

Also I think I'm missing the tricky part. Couldn't this be a bog-standard for loop?

   for (unsigned int i = N - 1; i > 0; i--){ ... }
Re:Few lesser known tricks, quirks and features of C by Jorengarenar on Sunday February 19, 2023 @02:49PM (#34861116)
The former executes loop when `i` is 0.

And we cannot change the comparison to `>=` in the later, because unsigned is always bigger or equal 0, thus we would get infinite loop.

Re:Few lesser known tricks, quirks and features of C by skribanto on Sunday February 19, 2023 @02:57PM (#34861198)
how would you iterate over every possible value of a unsigned int?
Re:Few lesser known tricks, quirks and features of C by mtklein on Sunday February 19, 2023 @05:59PM (#34862778)
Usually I use a do-while loop,

    unsigned char x = 0;
    do {
        printf("%d\n", x);
    } while (++x);
Re:Few lesser known tricks, quirks and features of C by NoZebra120vClip on Sunday February 19, 2023 @10:52PM (#34864747)
The unary complement operator should get you there:

  unsigned int x = 0;
  const unsigned int max = ~x;

  while (x <= max) {
     calc(x++);
  }
Or,

  #include <limits.h>

  const unsigned int max = UINT_MAX;
Re:Few lesser known tricks, quirks and features of C by kstenerud on Monday February 20, 2023 @12:17AM (#34865162)
Or if you only wanted to iterate halfway:

    unsigned int x = 0;

    while (x < ~x) {
        calc(x++);
    }
Or going down:

    unsigned int x = ~0;

    while (x > ~x) {
        calc(x--);
    }
Re:Few lesser known tricks, quirks and features of C by NoZebra120vClip on Monday February 20, 2023 @06:28AM (#34867147)
By "halfway", did you mean "off by one"?
Re:Few lesser known tricks, quirks and features of C by kstenerud on Monday February 20, 2023 @06:36AM (#34867180)
no
Re:Few lesser known tricks, quirks and features of C by mnaydin on Monday February 20, 2023 @06:40AM (#34867211)
This is an infinite loop since the expression

    x <= max
is always true.
Re:Few lesser known tricks, quirks and features of C by NoZebra120vClip on Monday February 20, 2023 @04:03PM (#34872876)
Heh! Good catch! That is what I get for not testing. After UINT_MAX, x wraps around to 0.
Re:Few lesser known tricks, quirks and features of C by mtklein on Sunday February 19, 2023 @05:58PM (#34862762)
It's worth noting that this does also work on signed types, so it can be a kind of handy idiom to see

   while (N --> 0) { ... }
and know it will execute N times no matter the details of the type of N.
[dead]
Re:Few lesser known tricks, quirks and features of C by HybridCurve on Sunday February 19, 2023 @05:21PM (#34862465)
> I remember once upon a time I thought C was fairly simple, so I decided to write a program to generate ASTs from C programs.

Oh man, I think we all have been this young and naive at some point.

I have spent time working with compilers for this purpose (having realized I did not want to attempt parsing source and generating the AST) and decided it is much easier to let them do the work. That being said, it can still be more than a handful (both GCC and Clang have their eccentricities) and depending on how you are using it you still might be in over your head.

When you start a project like this and end up failing because you simply do not have the depth of knowledge or time to see it to completion it often feels a bit demoralizing from the loss of investment. Truthfully though, having started many such ventures (emulators for 6502 and 80386 to name a few), you get all the benefit of experience from working on a difficult problems without the misery of debugging and model checking until everything until is more/less perfect. It's great fun, you learn a lot, and you should never avoid trying simply because it might be too much to handle.

Re:Few lesser known tricks, quirks and features of C by Joker_vD on Sunday February 19, 2023 @01:38PM (#34860432)
Never quite understood why compound literals are lvalues, but fine, whatever, I guess, it's so that you can write "&(struct Foo){};" instead of "struct Foo tmp; &tmp;"... which, on a tangential note, reminds me about Go: the proposals to make things like &5 and &true legal in Go were rejected because "the implied semantics would be unclear" even though &structFoo{} is legal and apparently has obvious semantics.
Re:Few lesser known tricks, quirks and features of C by leni536 on Sunday February 19, 2023 @02:41PM (#34861053)
In C compound literals have a relatively long lifetime compared to C++ temporaries. With these lifetime rules it makes sense that they are lvalues, although I like C++ rvalues (especially prvalues) more.

https://cigix.me/c17#6.5.2.5.p5

> If the compound literal occurs outside the body of a function, the object has static storage duration; otherwise, it has automatic storage duration associated with the enclosing block.

Re:Few lesser known tricks, quirks and features of C by cataphract on Sunday February 19, 2023 @03:53PM (#34861758)
It's useful when a function has a out or in/out struct parameter whose value at the end you're not interested in. Or in functions where the struct is an input parameter, but they return it as a return value too, which you can then assign to a pointer variable or immediately pass to another function.

Note that the struct values thus created have longer lifetimes than temporary C++ objects created directly inside the argument list of a function call.

Re:Few lesser known tricks, quirks and features of C by flohofwoe on Monday February 20, 2023 @07:37AM (#34867523)
That's extemely useful for invoking a function that takes a pointer to a struct:

   func(&(bla_t){ .x = 0, .y = 1 });
Re:Few lesser known tricks, quirks and features of C by gallier2 on Monday February 20, 2023 @09:15AM (#34868247)
Compound literals are anonymous variables, i.e. like variables except that there is no label visible in the C program. If you look at the assembly you'll see that they are declared exactly like a variable except with a compiler generated internal label.
Re:Few lesser known tricks, quirks and features of C by zabzonk on Sunday February 19, 2023 @02:33PM (#34860973)
the c training course at a popular uk training company (the instruction set) had duff's device on something like page 5 of their c course - expunging it was one of the first things i did when i joined them. there were many others.
Re:Few lesser known tricks, quirks and features of C by zabzonk on Sunday February 19, 2023 @04:14PM (#34861932)
i don't ask this too often - but what is wrong with this comment?
Re:Few lesser known tricks, quirks and features of C by bombcar on Sunday February 19, 2023 @06:41PM (#34863082)
I presume you angered the Duff Defenders (there are those that feel C shouldn’t be taught unless you’re taught all the weird things it can do).
Re:Few lesser known tricks, quirks and features of C by zabzonk on Sunday February 19, 2023 @06:46PM (#34863125)
yes, that was probably my feeling at the time. but perhaps a bit much for people struggling with compiling and running hello world.
Re:Few lesser known tricks, quirks and features of C by milgra on Sunday February 19, 2023 @03:36PM (#34861588)
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 .
Re:Few lesser known tricks, quirks and features of C by 3836293648 on Sunday February 19, 2023 @07:38PM (#34863529)
How do you handle third party headers?
Re:Few lesser known tricks, quirks and features of C by milgra on Monday February 20, 2023 @02:22AM (#34865861)
I just include them, everything works as before. If I have to create a library then I create a separate header file for the api functions and only the internals are headerless.
Re:Few lesser known tricks, quirks and features of C by gavinray on Sunday February 19, 2023 @08:09PM (#34863765)
This is great!
Re:Few lesser known tricks, quirks and features of C by enriquto on Monday February 20, 2023 @01:52AM (#34865701)
I love this. Somehow it feels more elegant than "header-only" libraries.
Re:Few lesser known tricks, quirks and features of C by xigoi on Monday February 20, 2023 @02:00AM (#34865743)
How does this help? It just moves the content of the .h file to the .c file, but you still need to Write Everything Twice.
Re:Few lesser known tricks, quirks and features of C by milgra on Monday February 20, 2023 @02:19AM (#34865834)
It reduces file count in the project browser, renaming/refactoring is much simpler in one file, it just feels like working with a newer language.
Re:Few lesser known tricks, quirks and features of C by account42 on Wednesday February 22, 2023 @10:47AM (#34897396)
Is having two files really that much of a bother? I have my editor set switch between the .c(pp) and the .h with a keyboard shortcut and that seems easier than scrolling between declaration and definition when you want to change something.
Re:Few lesser known tricks, quirks and features of C by zwieback on Sunday February 19, 2023 @03:36PM (#34861592)
Be interesting to see when these features showed up. I learned C from the K&R book back in the day and it doesn't mention most of these.

Designated initializer is something I'll try to remember, seems handy.

Re:Few lesser known tricks, quirks and features of C by suprjami on Sunday February 19, 2023 @04:13PM (#34861922)
Designated initialisers were added in C99
Re:Few lesser known tricks, quirks and features of C by AceJohnny2 on Sunday February 19, 2023 @05:08PM (#34862357)
Yeah the K&R, while being a masterpiece of clarity and conciseness, is severely outdated in many important ways.

I wish there was some effort to create a modern version while preserving the clarity and conciseness of Kernighan and Ritchie.

Designated initializers in particular are extremely useful. I once halted a factory line for days because of a mistake they would have avoided.

Re:Few lesser known tricks, quirks and features of C by flohofwoe on Monday February 20, 2023 @07:54AM (#34867637)
Designated init and compound literals were added in C99. I think there are two reasons for those features not being better known:

1) C++ 'forked' their C subset before C99 (ca. "C95"), and while C++20 finally got its own version of designated init, this has so many restrictions compared to C99 that it is basically pointless.

2) MSVC hasn't supported any important C99 features until around 2016

Re:Few lesser known tricks, quirks and features of C by neverrroot on Sunday February 19, 2023 @03:54PM (#34861767)
It’s cool to have these, it’s fun to use them for fun. But please don’t use them in production code. Also don’t assume most of them will he known by other developers.
Re:Few lesser known tricks, quirks and features of C by Jorengarenar on Sunday February 19, 2023 @04:20PM (#34861976)
>Also don’t assume most of them will he known by other developers.

Given the title of the article, one ought to assume the opposite ;)

Re:Few lesser known tricks, quirks and features of C by suprjami on Sunday February 19, 2023 @04:16PM (#34861942)
Professional C developers definitely should be using at least designated init and FAM, standard features both added in C99 and currently 24 years old.
Re:Few lesser known tricks, quirks and features of C by neverrroot on Monday February 20, 2023 @06:04AM (#34867056)
Well, it’s either a lesser known trick or it’s something people should be using. In general using lesser known tricks it’s not a good idea for production code. But I understand there are cases where there is no good alternative, so it’s warranted.
Re:Few lesser known tricks, quirks and features of C by suprjami on Monday February 20, 2023 @06:41AM (#34867215)
* * *
Re:Few lesser known tricks, quirks and features of C by neverrroot on Monday February 20, 2023 @08:28AM (#34867858)
I was taking for granted the storyline, and assumed they are indeed lesser known and tricks. To me it’s never about what I know, it’s about what the others know, my production code is not mine alone, and I also don’t want to be responsible for it forever. So I try to be explicit and use no tricks wherever possible.
Re:Few lesser known tricks, quirks and features of C by suprjami on Monday February 20, 2023 @09:33AM (#34868418)
I agree with this in principle, but where do you draw the line between language features (good) and obscure tricks (bad)? Is your team really writing only ANSI C89 from the K&R 2nd edition book and ignoring the last ~35 years of language improvements?
Re:Few lesser known tricks, quirks and features of C by Jorengarenar on Monday February 20, 2023 @01:32PM (#34871120)
I mean, I titled the article "Lesser known trick, quirks and features of C". Not to mention the very first sentence:

> There are some tricks, quirks and features (some quite fundamental to the language!)

Re:Few lesser known tricks, quirks and features of C by Gigachad on Sunday February 19, 2023 @05:25PM (#34862499)
Please don’t use C at all in production if you can help it.
Re:Few lesser known tricks, quirks and features of C by jjgreen on Sunday February 19, 2023 @06:56PM (#34863216)
So no Unix, Linux, Bash, cURL, Ruby, ...?
Re:Few lesser known tricks, quirks and features of C by suprjami on Monday February 20, 2023 @04:09AM (#34866426)
No Windows or OSX either (yes I know OSX is a Unix). Looking forward to all the RIIR people using Redox as their daily driver.
Re:Few lesser known tricks, quirks and features of C by icedchai on Sunday February 19, 2023 @06:59PM (#34863250)
The entire world runs on C. Even if you’re not writing new C code, it is useful to understand.
Re:Few lesser known tricks, quirks and features of C by flohofwoe on Monday February 20, 2023 @07:45AM (#34867570)
Some of those are regular modern C features and definitely should be used, most importantly compound literals and designated init, since they make the code both safer and more readable (and I blame the Visual Studio compiler team for dragging their asses for 16 years to support at least a subset of C99 for those features to be 'lesser known').
Re:Few lesser known tricks, quirks and features of C by LegionMammal978 on Sunday February 19, 2023 @04:40PM (#34862136)
> volatile type qualifier

> This qualifier tells the compiler that a variable may be accessed by other means than the current code (e.g. by code run in another thread or it's MMIO device), thus to not optimize away reads and writes to this resource.

It's dangerous to mention cross-thread data access as a use case for volatile. In standard C, modifying any non-atomic value on one thread, while accessing it on another thread without synchronization, is always UB. Volatile variables do not get any exemption from this rule. In practice, the symptoms of such a data race include the modification not being visible on the other thread, or the modified value getting torn between its old and new states.

Re:Few lesser known tricks, quirks and features of C by Jorengarenar on Sunday February 19, 2023 @06:16PM (#34862902)
`volatile` is one of the things we need to pay attention to when dealing with threads, but as you notice it's not the only one.

Eskil Steenberg talks about it at 12:42 in his talk Advanced C: The UB and optimizations that trick good programmers. [0]

[0]: https://youtu.be/w3_e9vZj7D8?t=762

Re:Few lesser known tricks, quirks and features of C by plugin-baby on Monday February 20, 2023 @12:29AM (#34865233)
UB?
Re:Few lesser known tricks, quirks and features of C by G3rn0ti on Monday February 20, 2023 @01:05AM (#34865428)
„undefined behavior“
Re:Few lesser known tricks, quirks and features of C by mid-kid on Monday February 20, 2023 @05:03AM (#34866734)
These days it can be chained with _Atomic to achieve the desired effect. That said, oftentimes you need more serious synchronization mechanisms your library would provide.
Re:Few lesser known tricks, quirks and features of C by LegionMammal978 on Monday February 20, 2023 @12:27PM (#34870379)
_Atomic is indeed the correct qualifier to use for unsynchronized cross-thread access. The volatile qualifier doesn't add anything useful on top of that. Really, the only things volatile should be used for are MMIO, debugging, performance testing, and certain situations with signal handlers or setjmp within a single thread.
Re:Few lesser known tricks, quirks and features of C by mid-kid on Tuesday February 21, 2023 @03:09PM (#34886346)
From what I gather, _Atomic alone will not ensure that the variable contents are actually loaded every time you load them, and can optimize loops away as a result. You'll often want both.
Re:Few lesser known tricks, quirks and features of C by LegionMammal978 on Tuesday February 21, 2023 @09:22PM (#34890754)
Sure, in principle, compilers can combine certain repeated atomic accesses. But in practice, compilers respect the fact that intervening code takes a nonzero amount of time to run, and always try to load the latest value of the variable. (I am entirely unable to coerce a compiler into combining atomic accesses, even with memory_order_relaxed where it would theoretically be permissible.) Volatile accesses are the same in the sense that the compiler can move the rest of the code around it (and are known to have done so in practice): the only difference is that repeated volatile accesses can't be combined even in theory, and they can't be omitted even if the result is discarded.

What use case do you have in mind where this theoretical possibility would cause issues?

Re:Few lesser known tricks, quirks and features of C by clnq on Sunday February 19, 2023 @04:42PM (#34862154)
Do we have something like this for C++ (parts not shared with C)?
Re:Few lesser known tricks, quirks and features of C by HybridCurve on Sunday February 19, 2023 @06:29PM (#34862997)
Can't say for all, but I am reasonably certain C++ does not support designated initializers/sparse array definitions. Some of these features where added in more recent revisions to the C specification from which C++ has diverged from. I would expect most of the differences would become more pronounced starting C99.
Re:Few lesser known tricks, quirks and features of C by flohofwoe on Monday February 20, 2023 @07:52AM (#34867614)
In theory, C++20 has designated init, but it has so many restrictions compared to C99 that it is pretty much useless for real world code.
Re:Few lesser known tricks, quirks and features of C by int_19h on Sunday February 19, 2023 @04:49PM (#34862207)
One non-obvious thing about named function types is that they can also be used to declare (but not define) functions:

   typedef void func(int);
   func f;
   void f(int) {}
I don't think I've ever seen a practical use for this in C, though. In C++, where this also works, and extends to member functions, this can be very occasionally useful in conjunction with decltype to assert that a function has signature identical to some other function - e.g. when you're intercepting and detouring some shared library calls:

    int foo();
    decltype(foo) bar;
I suppose with typeof() in C23 this might also become more interesting.
Re:Few lesser known tricks, quirks and features of C by mtklein on Sunday February 19, 2023 @05:56PM (#34862746)
I have found this pretty handy for declaring a bunch of functions of all the same type, e.g. steps in a direct-threaded interpreter.

    typedef void Step(whatever...);

    Step add,sub,mul,div,
         load,store,
         etc...;
Re:Few lesser known tricks, quirks and features of C by torstenvl on Sunday February 19, 2023 @06:23PM (#34862961)
I've seen this used to define function pointers / callbacks in a "cleaner" way. I think Mg does this IIRC.
Re:Few lesser known tricks, quirks and features of C by mtklein on Sunday February 19, 2023 @06:51PM (#34863160)
Oh yes! I totally agree with that approach; I find it much clearer to typedef the function type rather than the function pointer type:

    typedef int (*CallbackPtr)(int,int);
    void foo(..., CallbackPtr callback);
always reads less clearly to me than

    typedef int Callback(int,int);
    void foo(..., Callback* callback);
I find this especially useful in C++ where the callback type could conceivably be some other type like std::function. Seeing that * helps me know at a glance it's probably just a plain old function pointer.

Though I think maybe clearest of all is to not use a typedef, provided it doesn't cause other readability problems:

    void foo(..., int (*callback)(int,int));
(Not meaning to steal your thunder here... just wanted to write out an example in case anyone else was curious.)
Re:Few lesser known tricks, quirks and features of C by int_19h on Monday February 20, 2023 @01:19AM (#34865502)
At that point you might as well typedef the function pointer type anyway, since it's just another *, and const/volatile variations for functions don't make sense.
Re:Few lesser known tricks, quirks and features of C by AceJohnny2 on Sunday February 19, 2023 @05:23PM (#34862478)
Compound Literals in C are great. They're no surprise to anyone coming from more sophisticated languages, but I've never seen them used in the C codebases I've worked on.

What with C also allowing structures as return values, another rarely-used feature, they're really useful for allowing a richer API than the historical `int foo(...)` that so many people are used to seeing.

C has so much legacy that it's really hard for even decades-old (C99!) feature to impose themselves. Or perhaps that's MSVC's lagging support that's to blame :p

Re:Few lesser known tricks, quirks and features of C by pjmlp on Monday February 20, 2023 @02:20AM (#34865848)
MSVC supports C11 and C17, minus the C99 stuff that was made optional in C11.

Anyway given the option, one should always favour C++ over C, if they care about secure code, which while not perfect it is much better than any C compiler will do.

Re:Few lesser known tricks, quirks and features of C by AceJohnny2 on Monday February 20, 2023 @04:15PM (#34873007)
> Anyway given the option, one should always favour C++ over C

Eh. I work in embedded, where C reigns supreme. C++ has its own issues in the area, namely that you need to construct your own sub-dialect that removes some features of C++ to make it fit embedded constraints. Commonly, it's C++-but-no-exceptions, sometimes C++-but-no-templates, and others.

That said, I'll grant that us embedded developers are effectively "traumatized" and have difficulty accepting new approaches because we're too focused on certain paradigms that are no longer relevant (See my previous about returning structures, which has encountered responses like "but then it might do an extra memcpy()!!11")

Re:Few lesser known tricks, quirks and features of C by account42 on Wednesday February 22, 2023 @10:55AM (#34897544)
> sometimes C++-but-no-templates

I can understand exceptions, but what constraints require you to ban templates? If its just code size then it seems a bit arbitrary to ban them completely.

AFAIK most users of C++ do ban some features in their projects so I don't see why that specifically is holding embedded back. Disabling exceptions specifically is something that is not unheard of outside embedded either.

Re:Few lesser known tricks, quirks and features of C by AceJohnny2 on Monday February 20, 2023 @06:19PM (#34874231)
> MSVC supports C11 and C17, minus the C99 stuff that was made optional in C11.

Sure now, it took them 16 years for some C99 stuff!

https://learn.microsoft.com/en-us/cpp/overview/visual-cpp-la...

Re:Few lesser known tricks, quirks and features of C by icedchai on Monday February 20, 2023 @04:03PM (#34872882)
For many, I think "C" is still "C89."

I remember working on a commercial project in the mid-2000's that still had #ifdefs for K&R C prototypes (meaning, pre-ANSI C.) This was a recent-ish project at the time, started in 2000. Were people going to go back in time and compile it on an old architecture? I doubt it.

C moves slow.

Re:Few lesser known tricks, quirks and features of C by tastysandwich on Sunday February 19, 2023 @05:32PM (#34862557)
"Expert C Programming: Deep C Secrets" is a really good book to learn a lot of C tricks and quirks, plus some history. I read it a few years ago and loved it.

I was a grad when I read it and remember annoying my older coworkers for a few weeks with little gotchas I picked up. "hey what do you think THIS example prints?" "Stop sending me these!"

Re:Few lesser known tricks, quirks and features of C by Jorengarenar on Sunday February 19, 2023 @06:40PM (#34863066)
I'll need to check it out. Thanks!
Re:Few lesser known tricks, quirks and features of C by jjgreen on Sunday February 19, 2023 @06:40PM (#34863068)
Fabulous book, includes a section "Bus Error, Take the Train" explaining the "bus errors" one found on Sun hardware ...
Re:Few lesser known tricks, quirks and features of C by defrost on Sunday February 19, 2023 @07:08PM (#34863320)
When I wrote a lot of cross platform performant numerics I loved the bus error thrown by the Sun machines.

In essence it was a RISC machine saying "I can't deal with unaligned data" and a sign that code was (say) storing a 32 or 64 bit int that straddled a word boundary and the hardware was not coping on a MOV.

Why did that matter and why was it good thing?

It forced programmers to think about data alignment and resulted in code that run faster on CISC Intel chips.

The dirty secret about Intel chips was they "just did it" w/out complaint - and it slowed them down significantly on pipelined computations if they were constantly double handling unaligned data to get it from memory (across a word boundary) to bus (aligned for transit) to memry again (across a word boundary).

Re:Few lesser known tricks, quirks and features of C by somewhereoutth on Sunday February 19, 2023 @05:35PM (#34862574)
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'

Re:Few lesser known tricks, quirks and features of C by Jedd on Sunday February 19, 2023 @05:49PM (#34862692)
I don't believe those are functionally / semantically equivalent - couldn't care less does imply a min() value of care.

In contrast, the author is suggesting a comparative only.

And, on careful re-reading, I suspect the author is having a play on syntax & semantics here -- the context of the quote is:

> You may ask, since when C has such operator and the answer is: since never. --> is not an operator, but two separate operators -- and > written in a way they look like one. It's possible, because C cares less than more about whitespace.

Given that '--' is decrement (kind of 'lessen') and > is greater than (kind of 'more'). Perhaps I am reading too much into that.

(I feel 'couldn't care less' is perhaps more common in northern America than elsewhere, and while TFA has a Gabon TLD, appears to be resident in Poland, so automatically receives a lot of leeway in their use of idiomatic English.)

Re:Few lesser known tricks, quirks and features of C by Jorengarenar on Sunday February 19, 2023 @06:38PM (#34863055)
Hah, unfortunately this bit of "poetry" wasn't intentional. I just meant that C does care about whitespace, just not a lot.
Re:Few lesser known tricks, quirks and features of C by somewhereoutth on Monday February 20, 2023 @04:43AM (#34866621)
Ah apologies - I missed that subtlety. Unfortunately the whole 'could care less' debacle has left me somewhat triggerable.

'cares not so much' / 'doesn't care so much' might also work in your context.

Re:Few lesser known tricks, quirks and features of C by zabzonk on Sunday February 19, 2023 @06:13PM (#34862883)
c does care about whitespace - compare:

    int x;
with:

    intx;
Re:Few lesser known tricks, quirks and features of C by teo_zero on Sunday February 19, 2023 @07:19PM (#34863399)
Try removing spaces here:

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

  address = mask & &object;
Or here:

  a = b - --c;
Re:Few lesser known tricks, quirks and features of C by teo_zero on Sunday February 19, 2023 @07:34PM (#34863500)
I think the 5[arr] deserves more love.

  // traditional syntax:
  boxes[products[myorder.product].box].weight
  // index[array]:
  myorder.product[products].box[boxes].weight
Re:Few lesser known tricks, quirks and features of C by Jorengarenar on Sunday February 19, 2023 @07:53PM (#34863639)
Don't mind if I do
Re:Few lesser known tricks, quirks and features of C by panzi on Sunday February 19, 2023 @07:40PM (#34863549)
Before reading it, does it include the array[index] == index[array] thing again? reading Yep it does. :D
Re:Few lesser known tricks, quirks and features of C by Razengan on Sunday February 19, 2023 @11:50PM (#34865011)
I wish there was a language "between" assembly and C: basically assembly with some quality-of-life improvements.

Shortcuts to reduce redundant chores (like those multiple instructions to load one 64-bit number into an ARM register) but minimal "magic" or unintended consequences as in C. Things like maybe a function call syntax like:

CALL someFunc(R1: thingForRegister1, @R7: pushR7ThenPopOnReturn, R42: [memoryAddressForR42])

and the function might be defined as:

someFunc(R1 as localNameForR1, R7 as oneMoreThing, R42? as optionalArgument)

and so on. (but anyone could come up with better ideas than me)

Re:Few lesser known tricks, quirks and features of C by xigoi on Monday February 20, 2023 @02:36AM (#34865941)
I think QBE might be what you're looking for?

https://c9x.me/compile/

Re:Few lesser known tricks, quirks and features of C by spc476 on Monday February 20, 2023 @04:11AM (#34866432)
You just need a decent assembler with macro support. Here's a few lines of code I have for 32-bit x86 code:

    PRINTF "main_task: sf=%p",ebp
    PRINTF " sf: 1=%d 2=%d 3=%d 4=%d",dword [ebp+8],dword [ebp+12],eax,ebx
I'm using NASM and it wasn't hard to write the macro to do so.
Re:Few lesser known tricks, quirks and features of C by jokoon on Monday February 20, 2023 @05:41AM (#34866947)
I'm currently trying to make a programming language that translates to C. I've started with a pseudo BNF parser.

I started reading the C BNF and I have to admit that I was not prepared at all. It's not as easy as it sounds.

I cannot imagine how difficult it must be to maintain a modern C++ compiler.

Re:Few lesser known tricks, quirks and features of C by lionkor on Monday February 20, 2023 @06:51AM (#34867269)
Yeah, good luck hahaha

There is a reason why modern languages use keywords like "func", "def", "fn", "var", "let" to discern between different types of declarations, for example. I dont think many languages are LL(k) (please correct me if im wrong), but C is as far away from that as it gets, for small k.

Re:Few lesser known tricks, quirks and features of C by Gibbon1 on Monday February 20, 2023 @05:57PM (#34874049)
I've thought it would be nice to add func to the language. Even if it's just sugar it would help. Type inference + allowing functions to return an anonymous struct or a tuple would be super.
Re:Few lesser known tricks, quirks and features of C by augustk on Monday February 20, 2023 @06:59AM (#34867301)
There are three macros which I find indispensable and which I use in all my C projects, namely LEN, NEW and NEW_ARRAY. I keep them in a file named Util.h:

  #ifndef UTIL_H
  #define UTIL_H

  #include <errno.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>

  #define LEN(arr) (sizeof (arr) / sizeof (arr)[0])

  #define NEW_ARRAY(ptr, n) \
     (ptr) = malloc((n) * sizeof (ptr)[0]); \
     if ((ptr) == NULL) { \
        fprintf(stderr, "Memory allocation failed: %s\n", strerror(errno)); \
        exit(EXIT_FAILURE); \
     }

  #define NEW(ptr) NEW_ARRAY(ptr, 1)

  #endif
With these in place, working with arrays and dynamic memory is safer, less verbose and readability is improved.
Re:Few lesser known tricks, quirks and features of C by GnarfGnarf on Monday February 20, 2023 @07:09AM (#34867360)
I found a lot of bugs went away when I switched to STL (Standard Template Library) arrays and ditched managing my own memory. That's C++, I guess it's not available in straight C?
Re:Few lesser known tricks, quirks and features of C by krapp on Monday February 20, 2023 @07:16AM (#34867397)
>That's C++, I guess it's not available in straight C?

No, because C doesn't have templates. The best you can do for a "vector" in C is macros like above, that also realloc, or write an API around structs for each type.

Re:Few lesser known tricks, quirks and features of C by GnarfGnarf on Thursday February 23, 2023 @12:51PM (#34913906)
Too bad. STL deque's are non-contiguous, allow for much bigger arrays. I had an application that used vector<>, ran out of contiguous memory. deque<> solved the problem.
Re:Few lesser known tricks, quirks and features of C by augustk on Monday February 20, 2023 @07:56AM (#34867650)
It's even easier if you use a garbage collector, like for instance libgc. Then you just replace

  (ptr) = malloc((n) * sizeof (ptr)[0]);
with

  (ptr) = GC_MALLOC((n) * sizeof (ptr)[0]);
in the macro and don't have to worry about calling free.
Re:Few lesser known tricks, quirks and features of C by Gibbon1 on Monday February 20, 2023 @05:48PM (#34873953)
With gcc you can use this to get the elements of an array.

   // will barf if fed a pointer
   #define sizeof_array(arr) \
       (sizeof(arr) / sizeof((arr)[0]) \
       + sizeof(typeof(int[1 - 2 * \
       !!__builtin_types_compatible_p(typeof(arr), \
       typeof(&arr[0]))])) * 0)
Re:Few lesser known tricks, quirks and features of C by mnaydin on Monday February 20, 2023 @07:52AM (#34867615)
I am not able to understand how

  int (*ap3)[900000] = malloc(sizeof *ap3);
is nicer than

  int *a = malloc(900000 * sizeof *a);
Notice that, in the former case, the array elements must be accessed as (*ap3)[i] whereas in the latter case the usual method a[i] is fine.
Re:Few lesser known tricks, quirks and features of C by syockit on Monday February 20, 2023 @09:55AM (#34868622)
Me neither. In the VLA use cases page he does that with multidimensional array too.

    int (*arr)[n][m] = malloc(sizeof *arr);
which you have to access with

    (*arr)[i][j]
I prefer doing

    int (*arr)[m] = malloc(n*sizeof(*arr));
though this separates m and n to be one on left side while the other on the right side, it allows me to index directly

    arr[i][j]
Re:Few lesser known tricks, quirks and features of C by teo_zero on Tuesday February 21, 2023 @03:16AM (#34878256)
You don't use this technique to define a new array, but to get a pointer to an array you already have.

The goal is to have a pointer to the array, and not a pointer to the first element of the array.

Whether this is "nicer" or not, and whether this is what you need in your application, are out of the scope of the fine article.

Re:Few lesser known tricks, quirks and features of C by michaelcampbell on Tuesday February 21, 2023 @06:42AM (#34879892)
When I coded C my go-to for fun stuff like this was Peter Van Der Linden's "Deep C Secrets" book. One of those I don't need, but wish I hadn't sold.
Re:Few lesser known tricks, quirks and features of C by ljosifov on Thursday February 23, 2023 @12:09PM (#34913258)
Great read, and lead me to "When VLA in C doesn't smell of rotten eggs" https://blog.joren.ga/vla-usecases and this:

  int n = 3, m = 4;
  int (*matrix_NxM)[n][m] = malloc(sizeof *matrix_NxM); // `n` and `m` are variables with dimensions known at runtime, not compile time
  if (matrix_NxM) {
      // (*matrix_NxM)[i][j] = ...;
      free(matrix_NxM);
  }
Well, that makes much easier a few things I'm doing atm, really glad I read it.