
Why does the C preprocessor interpret the word “linux” as the constant “1”? - dcro
http://stackoverflow.com/q/19210935/1027148
======
simias
And that's why, in my opinion, non capitalized macros are always evil (yes,
I'm looking at you linux kernel).

When I see a lowercase symbol used as a variable, I expect it's going to be
some actual global variable. When I see a lower case symbol used like a
function I expect it's an actual function. And then comes the day I want to
take the address of the "function" and it fails. Or worse, I make a syntax
error somewhere and because of the macro expansion it gives me the most
perplexing error message in the world and it takes me 5 minutes and digging
through 4 levels of include files to realize I forgot a colon or something.

Not to mention the mess if the macro is poorly implemented and does things
like using a parameter several times which causes hard to catch undefined
behaviours in the application. Nothing worse than having a seemingly harmless
code like "foo(a++)" turn into the bug of doom because you didn't know foo was
a macro. Please don't do that.

On the other end when I get a weird behaviour/error message around a
capitalized symbol I automatically think that it must be a macro and go dig
for the definition.

~~~
pcwalton
Yup. This is why in Rust macros have to end with a ! (and syntax highlighters
know about this). This was a hard call, because it prevents using macros to
create forms that look exactly like the built-in ones, but it prevents issues
such as the one described in the OP.

~~~
simias
Ah! That's great, I didn't know that. The more I hear about rust the more I
like it. But then I'm reminded that it bakes garbage collection into the core
language...

Oh well, perfection is no of this world.

~~~
adrusi
There's a project, zero.rs, that lets you have no runtime in rust. It's been
shown that it's possible to make a simple kernel with it without too much
pain. The disadvantage, of course, is that libraries will use garbage
collection, and as soon as it's used, you get the runtime, so you can only use
certain libraries designed for zero.rs, which causes fragmentation.

All this would happen if gc was in the std library anyway though.

~~~
simias
Fair enough. I just have to cross my fingers and hope the GC won't catch on
then! :)

~~~
kibwen
We strive to avoid GC like the plague in the stdlib, and the language itself
encourages users to do the same. I wouldn't go so far as to say that we try to
make it _hard_ to use GC in Rust, but we definitely believe that it's
currently too easy to resort to it over better alternatives. This is why we're
moving it into a library.

~~~
Serow225
As a thought experiment, what would happen if the GC was removed altogether?
What consequences would that have (good and bad)?

~~~
kibwen
No thought experiment necessary, you can do this today in two ways:

1) We have an attribute that you can stick in a module that will throw an
error at compile time if a managed pointer gets used anywhere in that module,
including in its dependencies. (Note: this is still experimental, and I'm not
sure if it actually works yet.)

2) It's possible to write Rust entirely without a runtime, which means your
result binary just plain won't contain any of the machinery for GC, tasks, or
TLS (task-local storage).

This second approach does have consequences. Bad: random bits of the standard
lib won't be usable, since our preferred means of error handling uses TLS (and
some functional/persistent datastructures will use GC to handle cyclical
pointers, since that's our only internally acceptable use case for GC). We
have plans to look at dividing the stdlib into "usage profiles" to allow users
to selectively disable certain runtime features while still remaining aware of
exactly which pieces of the stdlib are still usable.

But the good consequences of disabling the runtime are that if your code
exposes a C ABI, then you can write a library that can be called from any
other language with a C FFI (i.e. basically every language, ever). This is
actually one of my favorite things about Rust.

------
army
I spent at least an hour a while ago trying to track down a bug that turned
out to be caused by exactly this. I couldn't work out what was happening until
I looked at the preprocessor output.

~~~
twoodfin
I'm increasingly turning to -E to debug these hard-to-understand problems. I'd
love a -E2 or what-have-you that would be even more verbose, and list all
preprocess transformations applied to a line and the source lines where they
were defined.

Unfortunately, the standard preprocessor output doesn't provide a convenient
way to do this without a comment format. I guess you could use a do-nothing
#pragma.

Eventually, I'm sure somebody will spin up some extension to clang to show you
the complete evolution of a block of code and what other code contributed to
that evolution.

~~~
simias
Emacs has a "c-macro-expand" function which is quite hackish but extremely
useful, IMO: it attempts to macro expand the region.

For instance running it on the following code in the middle of a C source
file:

    
    
        #define BOGO_MAX(a, b) a > b ? a : b
    
        int test()
        {
          return BOGO_MAX(3 + 4, 5);
        }
    

Creates a new buffer containing:

    
    
        int test()
        {
          return 3 + 4 > 5 ? 3 + 4: 5;
        }

~~~
tedunangst
How well does that play with ifdef? The problem is rarely what does this macro
expand to, but _which_ macro is going to be expanded.

~~~
simias
Well, I guess it depends on what your code looks like.

That being said if I'm not sure if some code is being compiled I just add an
"#error foo" and rebuild. Or even simpler I just type in some garbage to
trigger a compilation error.

------
lclemente
Just a note: This was on the stackoverflow weekly newsletter yesterday. If
you're interested in more questions like this it's worth to check it out, I
like it a lot.

~~~
Semaphor
For anyone wondering where to subscribe:
[http://stackexchange.com/newsletters](http://stackexchange.com/newsletters)

PS: That's one of the few reddit customs I really like "link for the lazy" :)

------
alttag
While I can't imagine much discussion here that couldn't occur on SO, I did
want to say thank you for posting this. I found it quite interesting.

~~~
TeMPOraL
+1, I love those interesting Stack Overflow (and Stack Exchange) posts that
started to appear here every other week. I always learn something
new/interesting from them. Thank you dcro :).

~~~
brey
no doubt the SO question will soon be closed as "not a question" or "too
interesting" or some other draconian response :(

~~~
Karunamon
They'll lock it to keep newbies away if nothing else, but I doubt it'll get
shut down. This is a "good fit" for the Stack sites though - it's a direct
question with one single direct answer.

------
blueblob
This is awesome, I am going to divide by linux in my code everywhere in an
attempt to obfuscate what I am doing.

~~~
berntb
At least anyone trying to port your code to Windows will be a bit surprised...
:-)

Edit: Or /.*BSD/. :-(

~~~
yk
Non portability to Windows is a feature.

------
anttiok
If you're in the habit of writing "struct sockaddr_in sin;", you'll probably
be tempted to write "struct sockaddr_un sun;". Just don't expect that code to
compile on Solaris.

~~~
robmcm1982
Is that just hardcoded into the preprocessor itself? Or is part of ANSI C.
Wondering if the MS C++ compiler will do this well.

~~~
simias
It's not and can be tuned using compiler options as mentioned in TFA.
Definitely not standard.

------
sramsay
Hacker News C-discussion response template:

"That's why [insert other language] has [insert feature]. This avoids some of
the edge cases in [insert popular non-C language] along the lines of [insert
unused obscure language]. Early benchmarks suggest it's almost as fast as C!"

------
CamperBob2
More or less equivalent to the question, "Why is clang/llvm running roughshod
over gcc?" It's the sum of a lot of really questionable decisions, like this
one, made over a very long time.

------
Theriac25
It's quite sad that you must specifically ask for conformance.

------
stonewhite
Doesn't name Keith Thompson ring a "bell"?

~~~
_kst_
Ding!

(No relation to Ken Thompson, if that's what you were thinking.)

------
blablabla123
Linux is No. 1

~~~
marcosdumay
Unless you compile it in Windows.

------
mmagin
One could argue the real problem here is C's weak typing and lack of a proper
boolean type.

------
icedchai
Wow. This would've been amazing news... back in in 1992.

~~~
_kst_
Which makes it amazing news to people who weren't programming back in 1992.

~~~
BlackDeath3
Some people here likely weren't even _born_ in 1992.

