News for hackers. Stuff that matters.
Re:Learning that you can use unions in C for grouping things... by WalterBright on Sunday August 01, 2021 @07:07PM (#28031087)
> 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... by cryptonector on Sunday August 01, 2021 @10:22PM (#28032250)
Having made a significant contribution to Simon Tatham's PuTTY, I have to respectfully disagree. At the time the entire SSHv2 key exchange and user authentication protocols were implemented in a single function using a massive Duff's device (for asynchrony) implemented with C metaprogramming macros. It was a surprisingly pleasant experience.
Re:Learning that you can use unions in C for grouping things... by pjmlp on Monday August 02, 2021 @03:21AM (#28033801)
There is a reason why such clevernesses are forbiden by security standards like MISRA-C.
Re:Learning that you can use unions in C for grouping things... by zerr on Sunday August 01, 2021 @07:53PM (#28031429)
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... by CamperBob2 on Sunday August 01, 2021 @08:31PM (#28031628)
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... by zerr on Monday August 02, 2021 @03:41AM (#28033916)
When it comes to cross-platform code, you build for several platforms, so the block is active (for particular platforms) and maintained.
Re:Learning that you can use unions in C for grouping things... by WalterBright on Sunday August 01, 2021 @09:01PM (#28031824)
> 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.

Re:Learning that you can use unions in C for grouping things... by jjnoakes on Monday August 02, 2021 @12:57AM (#28033055)
> Conditional compilation is an optimization, not a semantic intent.

Why can't it have semantic intent? I frequently use it for cross-platform adjustments, and those don't usually compile on the defined-away platform.

Re:Learning that you can use unions in C for grouping things... by WalterBright on Monday August 02, 2021 @03:30AM (#28033854)
> those don't usually compile on the defined-away platform

Then you're doing it wrong :-/

All these can be made to work.

P.S. compiling successfully is not the same thing as linking successfully. Think stubs and deciding which files to link together.

Re:Learning that you can use unions in C for grouping things... by zerr on Monday August 02, 2021 @03:46AM (#28033948)
Making it clear in the code itself that something is platform specific is useful as well. Also, I'd say such stubs and extra files would clutter the project.
Re:Learning that you can use unions in C for grouping things... by WalterBright on Monday August 02, 2021 @04:58AM (#28034401)
I tried it your way for years. It's common practice in the industry. I have written and seen plenty of rats' nests of #if and #ifdef snarls so bad one cannot figure out what is being compiled and what isn't without running a just-the-preprocessor pass. It will often #if on the wrong condition, like operating system when it's a CPU dependency.

Rewriting it the way I suggest tends to force a cleanup of all that. You'll like the results.

BTW, if you want to try transitioning to the next level, try getting rid of all the `if` statements, too!

Re:Learning that you can use unions in C for grouping things... by jjnoakes on Monday August 02, 2021 @10:22AM (#28036875)
They can be made to work by introducing stubs for every os/arch/compiler/dependency I support, but that's way more work for dubious gain.

And who is to say I'm doing it wrong? Just because conditional compilation CAN lead to a rat nest doesn't mean it MUST. And if it happens to be well-organized and works as is, there is no problem.

Re:Learning that you can use unions in C for grouping things... by WalterBright on Monday August 02, 2021 @02:03PM (#28040346)
> that's way more work for dubious gain

Oh, have I heard that before. Here's what happens, over the years, to such code:

1. #ifdef's on the wrong feature. For example, #ifdef on operating system for a CPU feature.

2. Overly complex #if expressions, that steadily get worse.

3. Fixing support for X that subtlety breaks F and Q support. It goes unnoticed because your build/test machines are not F and Q.

4. People having no idea what #defines to set on the command line, nor what the ones that are set are doing (if anything).

4. People having no idea how to fold in support for new configurations.

5. Code will #ifdef on predefined macros that have little or no documentation on what they're for or under exactly what circumstances they are set. If the writer even bothered to research that. gcc predefines what, 400 macros?

> Just because conditional compilation CAN lead to a rat nest doesn't mean it MUST.

Jyust yew wite, 'enry 'iggins, jyust yew wite!

Re:Learning that you can use unions in C for grouping things... by jjnoakes on Monday August 02, 2021 @02:33PM (#28040794)
> Here's what happens, over the years, to such code:

Over how many years? Some of my projects are 30+ years old and support a few dozen combinations of OSes, compilers, and architectures, and the method I described hasn't led to a rat's nest yet.

> #ifdef's on the wrong feature. For example, #ifdef on operating system for a CPU feature

Sure, same thing happens when you decide whether to compile in your stubs or not. But if I make a mistake, the code usually won't compile on the configuration in question; if you make a similar mistake, it'll compile with your stub, it might even link, but you'll get odd runtime behavior. Sounds worse.

> Overly complex #if expressions, that steadily get worse

All code gets worse over time and bit rots if you don't maintain it, I don't see things necessarily worse in this area.

> Fixing support for X that subtlety breaks F and Q support. It goes unnoticed because your build/test machines are not F and Q

If you aren't testing on tier one configurations, they shouldn't be tier one. And if a tier three configuration breaks when you do finally get around to testing it, it's tier three, so it gets fixed when it can be and there's no problem. Similar to normal code, I'd say.

> People having no idea what #defines to set on the command line, nor what the ones that are set are doing (if anything) > People having no idea how to fold in support for new configurations

These problems exist for normal code as well. Someone has to own the build configurations, and they have to be maintained, like anything else.

> Code will #ifdef on predefined macros that have little or no documentation on what they're for or under exactly what circumstances they are set. If the writer even bothered to research that. gcc predefines what, 400 macros?

We only use a handful, and they are fairly well documented. But even if they weren't, since the code works on all tier one platforms, we'd know if something was changed out from underneath us because it was underspecified or accidentally relied upon.

But again the same can happen with normal code and system headers, compiler extensions, etc - I don't see why pre-processor macros have to be singled out here.

> Jyust yew wite, 'enry 'iggins, jyust yew wite!

How long?

Re:Learning that you can use unions in C for grouping things... by shultays on Sunday August 01, 2021 @09:36PM (#28032015)

   The optimizer will delete bar() if FOO is a manifest constant that is not 3. 
Yes, but the compiler won't delete it and complain if bar is not defined. if constexpr is not a direct replacement for if macro
Re:Learning that you can use unions in C for grouping things... by WalterBright on Sunday August 01, 2021 @11:28PM (#28032575)
> the compiler won't delete it and complain if bar is not defined

    extern void bar();
will define it to the satisfaction of the compiler. The linker won't complain if the compiler removes the call to it.
Re:Learning that you can use unions in C for grouping things... by shultays on Monday August 02, 2021 @05:27AM (#28034565)
And then you have the issue of not having types. consider this

  void my_bar_class_type::bar(my_bar_type<my_bar_type_2>::my_bar_inside_type paramater);
and you are calling something like

   myObject->bar(mySecondObject.getWhatever());
You have to mock up like everything
Re:Learning that you can use unions in C for grouping things... by WalterBright on Monday August 02, 2021 @02:05PM (#28040371)
Or go up an abstraction layer so the type details are not needed.