Live data from Hacker News

Learning that you can use unions in C for grouping things into namespaces

utcc.utoronto.ca

71–80 of 150 posts

Re: Learning that you can use unions in C for grouping things into namespaces

#71

Earlier quoted context omitted.

Anytime macros are used for metaprogramming, it's time to reach for a more powerful language.

You might as well have written that "any time you're reaching for C, it's time to reach for a more powerful language". But if -sadly- you must use C, metaprogramming using macros is not a terrible thing.

> is not a terrible thing

It is a terrible thing. It's possible to do without them, and you'll like your code better. Your symbolic debugger and syntax directed editor will work properly. The poor schlub who has to fix the bugs in your code after you leave will be grateful. Your spouse will be happy and your children will prosper.

For example,

    #define foo(x) ((x) + 1)
replace with:

    int foo(int x) { return x + 1; }
The compiler will inline it for you. There's no penalty.

    #define FOO 3
Replace with:

    enum { FOO = 3 };
or:

    const int FOO = 3;
Replace:

    #if FOO == 3
    bar();
    #endif
with:

    if (FOO == 3) bar();
The optimizer will delete bar() if FOO is a manifest constant that is not 3.

Re: Learning that you can use unions in C for grouping things into namespaces

#72
post #61

Earlier quoted context omitted.

> I really don’t understand why they are not allowed. I don't, either. Such were in D from 2000 or so. I also don't understand why `class` in C++ sits in the tag name space. I wrote Bjarne in the 1980s asking him to remove it from the tag name space, as the tag name space is an abomination. He replied that there was too much water under that bridge. D doesn't have the tag name space, and in 20 years not a single pers…

The only explanation I saw was that C++ standards guys were horrified by the idea of unpredictable side effects as a result of initialization of a struct. I think C++ though is adding them. What I'd like in c is designated function parameters. // these the same bar(.a = 10, .b = 12); bar(.b = 12, .a = 10);

I suspect that to many C++ programmers, most initializations of structs have unpredictable side effects because of how complex they are ;)

Re: Learning that you can use unions in C for grouping things into namespaces

#73

Earlier quoted context omitted.

Linux kernel is large project and clearly C is sufficient for it, given the fact that migrating to C++ would probably be very easy (not using all C++ features, but just selected ones), yet it did not happen. I think that C++ is better than C, but C is not that bad, even for large projects.

> Linux kernel is large project and clearly C is sufficient for it Sure, and operating systems have been written in assmebly too. The question is whether it would be better than just sufficient if Linux were written in C++, today (ie C++17 or 20, not something old). Switching now probably wouldn't be feasible (even ignoring technical reasons, the kernel developer community is familiar with the C codebase and code sta…

Cantrill did a talk on which he touches on C, C++ and Rust for systems programming [1].

His tl;dr being that Rust feels very much like a proper systems programming language, and more of a « better C » than C++. I don't entirely know what to make of it, but my instinct is that something like C++ with such an opportunity space for baroque concoctions (leading to an obsession with design patterns) is just playing with fire.

[1] https://www.youtube.com/watch?v=LjFM8vw3pbU

Re: Learning that you can use unions in C for grouping things into namespaces

#74
post #35

Imo this is not “perverse”. In my vector library I alias a vec3 as float x,y,z and float[3] using this technique.

This is also known as the most common invocation of undefined behaviour in game programming. If you do this, write to y, then read from [1]. You are invoking undefined behaviour, and compilers doing different things here between windows, linux mac, and different compiler versions is a common cause of "why isnt my game working right on XXX, it works fine on YYY questions.

I don’t see the undefined behavior here?

Re: Learning that you can use unions in C for grouping things into namespaces

#75

Earlier quoted context omitted.

You might as well have written that "any time you're reaching for C, it's time to reach for a more powerful language". But if -sadly- you must use C, metaprogramming using macros is not a terrible thing.

> is not a terrible thing It is a terrible thing. It's possible to do without them, and you'll like your code better. Your symbolic debugger and syntax directed editor will work properly. The poor schlub who has to fix the bugs in your code after you leave will be grateful. Your spouse will be happy and your children will prosper. For example, #define foo(x) ((x) + 1) replace with: int foo(int x) { return x + 1; } Th…

Agree except the last example - the clarity of intent that you want a conditional compilation is lost. Also, non-optimized debug builds are affected.

Re: Learning that you can use unions in C for grouping things into namespaces

#76
post #18

Anonymous nested structs are also quite useful for creating struct fields with explicit offsets: #include #include #define YDUMMY(suffix, size) char dummy##suffix[size] #define XDUMMY(suffix, size) YDUMMY(suffix, size) #define PAD(size) XDUMMY(__COUNTER__, size) struct ExplicitLayoutStruct { union { struct __attribute__((packed)) { PAD(3); uint32_t foo; }; struct __attribute__((packed)) { PAD(5); uint16_t bar; }; str…

One of the very few things from C that I miss in C++ is anonymous structs and enums. I really don’t understand why they are not allowed. That is, C style enums don’t have to have a name but “type safe” (enum class) ones do. One classic use is to name an otherwise boolean option in a function signature; there’s typically no need to otherwise name it. C++ incompatibly requires a name for all struct and class declaratio…

... ? That's definitely not true, both anonymous structs and enums work fine in c++.

https://wandbox.org/permlink/ICaQJXCaVOt9mXdP

Re: Learning that you can use unions in C for grouping things into namespaces

#77
post #75

Earlier quoted context omitted.

> is not a terrible thing It is a terrible thing. It's possible to do without them, and you'll like your code better. Your symbolic debugger and syntax directed editor will work properly. The poor schlub who has to fix the bugs in your code after you leave will be grateful. Your spouse will be happy and your children will prosper. For example, #define foo(x) ((x) + 1) replace with: int foo(int x) { return x + 1; } Th…

Agree except the last example - the clarity of intent that you want a conditional compilation is lost. Also, non-optimized debug builds are affected.

I think it was RMS who argued that conditional compilation should be considered harmful in general. Code that you put in an inactive #if(def) block will not be maintained, and is basically guaranteed to rot. If it's needed in the future, it'll likely have to be rewritten from scratch.

According to this stance, any code that's suppressed by the C preprocessor should either be written in an if {} statement so that it will at least continue to compile as the surrounding code changes, or be replaced with comments describing what it does (or did), if it's important enough to keep track of.

Can't really think of many good counterarguments to this. Machine dependence might be one, but then you could argue that the preprocessor is being used to cover up for an inadequate HAL.

Re: Learning that you can use unions in C for grouping things into namespaces

#79
post #47

Earlier quoted context omitted.

Type punning/aliasing with unions is well defined in gcc. Linus even has a humorous rant about it on the topic: https://www.yodaiken.com/2018/06/07/torvalds-on-aliasing/ Sure, it's compiler-specific, but I'm already using `__attribute__((packed))` anyways.

All undefined behaviour is well defined for each compiler, what it really means is implementation defined and subject to change without notice or documentation with every compiler version or host os what flags are enabled or a thousand other things. Why use an approach which strictly relies on specific versions of specific compilers, rather than a completely portable and standard compliant struct with char array and…

What you're saying is very close to the common fallacious idea about UB, which is that the compiler and computer are machines, and therefore must have some deterministic behaviour when they encounter any given piece of code. But the point and meaning of the term "undefined behaviour" is that it describes the result of operations which are off limits for legal reasons. There is nothing good to be gained from trying to claim that GCC extensions are actually a kind of undefined behaviour. If you know what is meant by UB in the C standard, you won't muddy the waters like this.

"Somebody once told me that in basketball you can't hold the ball and run. I got a basketball and tried it and it worked just fine. He obviously didn't understand basketball." https://blog.regehr.org/archives/213

Re: Learning that you can use unions in C for grouping things into namespaces

#80
post #75

Earlier quoted context omitted.

> is not a terrible thing It is a terrible thing. It's possible to do without them, and you'll like your code better. Your symbolic debugger and syntax directed editor will work properly. The poor schlub who has to fix the bugs in your code after you leave will be grateful. Your spouse will be happy and your children will prosper. For example, #define foo(x) ((x) + 1) replace with: int foo(int x) { return x + 1; } Th…

Agree except the last example - the clarity of intent that you want a conditional compilation is lost. Also, non-optimized debug builds are affected.

> clarity of intent

Conditional compilation is an optimization, not a semantic intent.

> non-optimized debug builds are affected

The code size will be larger. Doesn't matter.

Post reply on HN