Live data from Hacker News

Lesser known tricks, quirks and features of C

blog.joren.ga

61–70 of 189 posts

Re: Lesser known tricks, quirks and features of C

#61

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

I think I'll use other example. Thanks!

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: Lesser known tricks, quirks and features of C

#62

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'

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: Lesser known tricks, quirks and features of C

#63
post #58

Earlier quoted context omitted.

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

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…

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: Lesser known tricks, quirks and features of C

#64
post #50

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…

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: Lesser known tricks, quirks and features of C

#65
post #47
post #7

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.

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

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: Lesser known tricks, quirks and features of C

#66

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.

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.

Re: Lesser known tricks, quirks and features of C

#67

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.

how would you iterate over every possible value of a unsigned int?

Usually I use a do-while loop,

    unsigned char x = 0;
    do {
        printf("%d\n", x);
    } while (++x);

Re: Lesser known tricks, quirks and features of C

#68
post #18

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

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

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: Lesser known tricks, quirks and features of C

#69
post #35

Earlier quoted context omitted.

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

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

There's more than one compiler.

Re: Lesser known tricks, quirks and features of C

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