Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Doesn't seem like the author really thought some of this through:

FTA: "The <nostdreturn.h> file according to the standard shall have exactly this content: "#define noreturn _Noreturn" Are you crying or laughing yet ?"

It's a compatibility constraint. They can't simply add new reserved words to the language because it will break preexisting code (c.f. all the old C headers with idenfiers like "bool" or "class" or "virtual" that don't build in C++). The underscore-followed-by-capital convention happened to have been reserved by ISO C90, so that's what they picked.

But they allow that this is ugly, so there's a new C1X header file you can include in new C1X code that makes the identifiers look like you expect they should. Obviously old code won't include this header and is insulated from the change. (I guess if you wanted to nit here, having a separate header for each new feature seems dumb to me. Why not a single <c1x.h> or the like?)

Compatibility is important, especially for languages like C with staggeringly large bases of mature code. For an example of what happens when you break compatibility in the name of "progress" see Python3, which years on is still not installed by default anywhere, and probably never will be.



First of all: You're wrong, the compatibility is the other way around: The old code will have to include <stdnoreturn.h> if they used the "noreturn" compiler-specific keyword, while waiting for the glacial ISO WG progress.

Second: There are two kinds of compatibility: Forwards compatbility and backwards compatibilty.

There is a finite number of existing programs whereas the number of future programs to be written is unbounded and very likely to be much higher over time.

Therefore forwards compatibility is always, by definition, more important than backwards compatibility, and you should never penalize future programs and programmers for the misdeeds and sloppines of the past programs and programmers.

Besides: I have yet to see a compiler that didn't have flags to make it compile to a slew of older dialects of C, so if C1X happens to break your old code, you set such an option, or you fix your source code.

There, fixed it for you.

The "Backwards compatibility, no matter the cost" mentaility is costing us dearly in the quality of the tools we have work with in the future, while providing us no relevant new benefits.

Crap like <stdnoreturn.h> is just pointless ornamentation, cluttering our source code.


No, you're wrong. The old code will have something like

typedef char bool

And thus compiling this code in C99 would not work if bool were a keyword of the language. That is why the boolean datatype is called _Bool, so it doesn't clash with old code. In new code, you can still use the bool datatype, but instead of defining it yourself with char or int, you should better use a typedef of the _Bool datatype in stdbool.h


Your attitude is rediculous... Let code break! Make sure there is a __c1x macro and maintained projects will take 30 seconds to fix. Unmaintained projects will die, yay!


I will never purchase a compiler made by you or someone who thinks like you. Sure, it will take 30 seconds to fix your puny 2000 line program that's contained in just a handful of files all of which you control and with no code generation engines or text transformation steps in its build chain. But it wouldn't be that easy for everyone.


If you don't value backwards compatibility, then perhaps you should not use a 40-year-old language with a standards committee that does value it.


I see no reason why he shouldn't express his opinion on the committee's goals re backward computability.

Defending the status quo by saying "well duh, you should know better, take it or leave it" is just a way of rejecting someone's contentions without actually addressing them. In a reasoned debate that's indefensible.

If he's wrong, tell him why rather than telling him to take his ball and go home.


This is from the Rationale for an International Standard for C, in the intro where they state their guiding principles from 2003 (http://www.open-std.org/jtc1/sc22/wg14/www/C99RationaleV5.10...):

Existing code is important, existing implementations are not. A large body of C code exists of considerable commercial value. Every attempt has been made to ensure that the bulk of this code will be acceptable to any implementation conforming to the Standard. The C89 Committee 20 did not want to force most programmers to modify their C programs just to have them accepted by a conforming translator.

Note that this guiding principle was listed first. The author disagrees with one of their fundamental guiding principles. My point is that he then has a fundamental disagreement with the purpose of the standard, and for that reason, perhaps he is using the wrong tool.

If someone has the guiding principle X, and someone else has the guiding principle !X, I contend that difference is irreconcilable.


Dennis Ritchie, C's creator, along with Ken Thompson, Unix' creator, and other Bell Labs people from the Computing Science Research Center thought the C standardization committee was wrong, so the Plan9 C compiler[1,2] is not ANSI compatible. Not only the standard library is nothing alike, the language itself is slightly changed in an incompatible way.

[1] http://cm.bell-labs.com/sys/doc/comp.html

[2] http://cm.bell-labs.com/sys/doc/compiler.html


tl;dr: if you don't value backwards compatibility, bend over backwards.


> The old code will have to include <stdnoreturn.h> if they used the "noreturn" compiler-specific keyword, while waiting for the glacial ISO WG progress.

Huh? stdnoreturn.h only makes sense with the new _Noreturn keyword. The old code can keep using __attribute__((noreturn)) or (if it was portable code) nothing at all, without including any headers.

> Crap like <stdnoreturn.h> is just pointless ornamentation, cluttering our source code.

I think C's "add seemingly randomly named include files to the top of your code to use different parts of the standard library" is pointless, and I'd like to see the whole standard library included by default (using some yet-to-be-invented more flexible PCH magic to ensure it doesn't slow down compilation). But in lieu of that, it's hardly a big jump from library to syntax - and if keeping backward compatibility isn't hard, why not do it?


I tend to agree with you about C include files, but observe that you can get more or less the same effect with a single "myproject.h" file included in your myproject-x source files.


> C's "add seemingly randomly named include files to the top of your code to use different parts of the standard library" is pointless

But doesn't most languages do this? Like java's imports (only a really small subset is included by default) or python. I would have thought that namespace separation is a good thing.


I don't use Java, but Python has a reasonably large set of builtins, and the base modules like os and sys provide a lot more - C would require a longer list of includes. Still, I would like to be able to write something like "mmap::mmap" and have Python automatically figure out what to import, keeping the namespace separation but eliminating the redundancy of explicit imports.

(maybe pick something other than double colons, heh.)


    python -m this | head -4 | tail -1
Or use Ruby and ActiveSupport::Dependencies.


Maybe the ISO committee is conspiring to destroy C with mediocrity so that a shiny new systems language can take its place, correcting C's deeper warts in the process.

That would be nice, if only I believed it.


Exactly. I've long since lost track of which shiny new systems language we're supposed to be using.


What do you think about D? ;)


D seems to be targeting C++ more than it does C.


Therefore forwards compatibility is always, by definition, more important than backwards compatibility, and you should never penalize future programs and programmers for the misdeeds and sloppines of the past programs and programmers.

Ha. You're adorable.

While I do support the general "hey, let's fix old code and not be slaves to backwards compatibility", the fact of the matter is that legacy code / libraries / whatever in C aren't merely misdeeds/sloppiness--you might as well complain about having to use the same molecules of metal in your tools that our ancestors did building Rome instead of making your own from subatomic particles.

There is a finite number of existing programs whereas the number of future programs to be written is unbounded and very likely to be much higher over time.

But in the future, it's all Javascript/Ruby/CSS/HTML5! Why worry about writing more C code? ;)


"""While I do support the general "hey, let's fix old code and not be slaves to backwards compatibility", the fact of the matter is that legacy code / libraries / whatever in C aren't merely misdeeds/sloppiness--you might as well complain about having to use the same molecules of metal in your tools that our ancestors did building Rome instead of making your own from subatomic particles.""""

Only you have to use the same molecules of metal by the laws of physics, while compilers you can IMPROVE. Heck, we even produce new metal alloys and materials all the time. So, the analogy is 100% flawed.


I've got one involving cars if you prefer. :)


  The "Backwards compatibility, no matter the cost" 
  mentaility is costing us dearly in the quality of
  the tools we have work with in the future, while
  providing us no relevant new benefits.
That is only because you don't have a vested interest in old code bases. (Taking a rough guess here: you're under 30?)


You have absolutely no idea what, or rather: who, you are talking about: I'm the second most active committer to FreeBSDs kernel over the project lifetime and I'm the author of Varnish, I even have C-code running in ATC systems, heck when it comes to that: My code scrambles your password.

It's exactly because I am responsible for so much old code that I say we should not cripple the future for it.


First off, I didn't realize. I'm sorry.

     I am responsible for so much old code that 
     I say we should not cripple the future for it.
I had to read that a few times. Are you advocating a clean break so that whatever that is future is clearly not called C or even purports to be backwards compatible with C? That would be difficult wouldn't it? It simply wouldn't get traction.


I'm not sure I have a coherent proposal. Clearly ISO-C is a cul-de-sac by now, and will have to be ditched. What we should replace it with is not clear to me.

It is a big problem that so many standards, requirements and tools (from EMACS to Coverity over lint) have their fingers in the C-syntax. The autocrap abomination is a further complication.

So I guess a good place to start is to swear that we will never touch or use the botched ISO-C thread API, and beat some sense into the WG14, by whatever means are available.


Perhaps the only place for C to go is for a final consolidation specification, which will be frozen for 50 years. You might even remove some broken parts of previous specifications, but with 50 years of stability, it gives a lot of confidence that any work would be worthwhile.

A long period of stability may also make it easy for C to interact with other languages. I'm out of my depth here. Some standard specifications for pinning memory from garbage collection, if Scheme could specify TCO, perhaps C-consolidation release could improve its toolability for things like Coverity; A better autoconf; Makefiles; Standard compilation error codes; Something that would clean up all the rough edges in supporting C compilers.


Do you think a new language (Go, maybe?) will take C's place, given your distaste for ISO's handling of the standard?


Dead post from ballard:

ballard 3 hours ago | link [dead]

Java was an over-reaction to C.

Go was a reaction to Java back to almost center.

C is close to hardware, which is important for things like game engine cores, video drivers, varnish and the list of use-cases goes on and on.

Finally, people tend to complain about their tools even when those tools work. Be thankful if you didn't have to write the tool yourself. But if you would feel compelled to complain, write a better one yourself first instead. :)

@phk: When was the last time you wrote inline asm in C to solve any problem on an non-embedded system? Mine was 1996.


Last time I wrote inline ASM was 2 days ago. I'm a kernel programmer, remember ?


Just curious: what was it for? Link to public commit etc would also be ok. Thx. I was the impression that all the asm code was abstracted away in rarely-changing header file macros?


I doubt any language will replace C ever, given the penetration it has, but maybe we could get a better C2X than the crap C1X seems to be. It would require a significant fraction of programmers to agree with me that C1X is crap in the first place.


I am mostly a Python programmer who still remembers C and I won't say "crap".

I will, however, say "ugly".


how true is it that one reason C is increasingly unlikely to be replaced is that cpus these days specifically optimise the performance of C-compiler-generated code?


phk under 30? hahaha. Does freebsd count as an old code base?

If you direct your remarks at what's being said instead of who (you think) is saying it, you wouldn't miss so wildly.


I don't think that's entirely fair. Sometimes who someone is, is a decisive factor in what arguments they present. It can give them a valuable jolt of insight to point out that they present those arguments because they are missing part of the view. Of course you should also explain why the arguments in themselves are wrong, but the main argument may be "you've never experienced X; those that have tend to argue Y, because of Z"


Age discrimination just makes you look like a fool.


It's very easy to make those arguments just by saying "From my experience doing X, you're wrong because..." without speculating about what the other person hasn't done.


on the contrary, I find communicating in this way a rather reliable method of talking in short hand. I was happy to be wrong, since phk illuminated another reason why some people may advocate breaking compatibility, and it is easy to get to his core arguments once his credentials were established.


I don't agree with your assertion that backwards compatibility isn't important, but I would like to point out that the very fact that C compilers allow you to use identifiers that are in the form _Word means that they are breaking backwards compatibility by introducing new keywords.

Many of the libraries on a typical Linux system (anything glib/gtk based, libxml2, etc.) use _Word extensively.


Initial underscore followed by a capital letter is a reserved "namespace" since 1990, as a previous commenter noted. (And for the record, identifiers that begin with two underscores are reserved for use by the implementation, and identifiers followed by a lowercase letter are guaranteed to be unreserved as long as they are file-scoped symbols, and not globally visible.)


Yes, I realize this, but since it's only "reserved" in the specification and the compiler doesn't enforce this, there is a massive amount of code that does this today.

The spec could contain, "don't add any bugs into your C programs" but that doesn't magically mean that everyone would write bug free code.

Reserving a namespace and not having a mechanism to enforce it was a massive fail on the part of the standards committee.


> Reserving a namespace and not having a mechanism to enforce it was a massive fail on the part of the standards committee.

How do you expect the compiler to enforce the "identifiers that begin with two underscores are reserved for use by the implementation" rule? Some things just belong in the documentation.


If the goal is to allow the introduction of new keywords, then it's fairly simple. Don't parse anything in the form __[a-z0-9$_] as anything but a keyword.

Problem solved. Instead, they did something awkward by trying to carve out namespaces for the stdlib too but quite frequently don't adhere to their own rules.


The goal is not just to allow for new keywords. Reserved identifiers are also intended to be used in system headers to protect implementation code from the unfortunate effect of user defined symbols.

Go and read your /usr/include/stdio.h (or equivalent). It will be filled with such symbols. Obviously the compiler must lex them exactly as it would unreserved symbols.

This is an unfortunately legacy of C's decision to pass compilation information around by textual inclusion, and isn't really fixable at this point.


System headers could use a #pragma _SystemIdentifiers, much like TeX's "makeatletter" and "makeatother" that allow packages to use @ in the name of internal symbols to avoid conflicts.

I do think compilers ought to have warnings for using identifiers in the reserved namespace. Most projects probably wouldn't trip over the ^_[A-Z] reserved space; however, numerous projects would trip over the reservation of any identifier containing two adjacent underscores.


That would require changing every single existing header that currently contains reserved identifiers. Do you have any idea how much work that is? Even if you could somehow magically enumerate and alter them all - and test them, since the necessary renaming of identifiers in non-system headers might introduce a bug - legacy versions would be floating around for years.

Conceptually a warning is a nice idea, but it just isn't practical.


Not necessarily. GCC, at least, avoids showing warnings in system headers unless explicitly requested. So, normally you'd only see warnings about the use of reserved identifiers in your own code.


But there are lots of places where these identifiers aren't keywords, and it is valid code (try writing a compliant stdlib without using them).

The problem is that too many people assume that their usage of C is the same as everyone elses. I don't want to be writing a system library and fighting my compiler everytime I put something in the symbol table that isn't in the C spec.


It's to allow use of any identifiers anywhere, not just keywords, without having to worry about conflicts with the including code.


Indeed. As a general rule, if you think the ISO committee has done something pointlessly moronic, there's a pretty good chance that there's more going on than you know about.


This is exactly how stdbool worked in C99 too. _Bool is the actual typename and stdbool.h includes a macro to normalize it.


"For an example of what happens when you break compatibility in the name of "progress" see Python3, which years on is still not installed by default anywhere, and probably never will be."

Python 3 is the default on some Linux distros (e.g. Arch Linux)...


breakage of pre-existing code is really a poor excuse for such craziness. Seriously do you prefer an error message during compilation that is easy to understand and not so difficult to fix or a language so tricky that nobody can read the huge reference manual. I fully agree with the author. Seek and hang the culprits !


That's not what C1X is for. It's a straightforward evolution of ISO C99 which adds features without breaking anything. If you want a similar low level language which is not compatible with legacy C you don't have to look far: history is littered with their carcasses.


One of those carcasses happens to be C99.


Think about C++: not only legacy C++ was broken by each standard, it was also broken by each compiler releases. The change of compiler release was always a journey.<br> It is normal that introduction of a new keyword breaks legacy C. A new standard is compatible with legacy code if the only adaptation required is to rename identifiers that collides with new keywords. There is no excuse for producing such a crap.


The issue always confuses me. The committee puts in a lot of effort to avoid introducing new keywords or repurposing obsolete keywords. This introduces some horribly overloaded keywords and awful syntax. Of course, new keywords break old code but what is so difficult about a grep-replace on your code base? The only reason I can come up with are the few corner cases where turning an identifier into a keyword can produce well-formed code with a different meaning but I have a hard time imagining such a thing. Can someone shed some light on this?


Pain now, or pain later? Most choose to put off the pain.

Python 3 chose pain now - and I think they made the correct choice - but three years later, people are still upset and many, many Python libraries have not made the transition.


To be fair, though, the Python core team envisioned a five-year transition plan and we are starting to see major frameworks make the switch. Django, for example, recently announced full Python 3 compatibility in their nightly builds.


I agree that's fair, hence why I think it's the right choice even given the pain. The reason I pointed out that it's been three years is that sometimes, it's not just a choice about pain now, but a prolonged pain starting now and maybe lasting years.


C++ also goes out of its way to avoid introducing new keywords for exactly the same reasons as C.


I think C++ ultimately proves what a poor idea that really was!


I know this is orthoganal to your point, but Arch Linux ships with python3 installed by default. Of course, python 2.7 is in the repositories, but you have to say /usr/bin/python2 to get to it. That breaks all those stupid build scripts that expect python 2.x to be installed in /usr/bin/python and nowhere else.


Wait... it's stupid to write a script that uses /usr/bin/python (or really "/bin/env python" per the convention in that community)? When those scripts were written, there was no "python2". It's certainly not their fault that "python" changed to be an interpreter for a different language.

This is exactly the problem. Distros (c.f. Red Hat, SUSE, Ubuntu) with large installed bases simply cannot ever ship a /usr/bin/python as anything but python 2 for exactly the same reason that the kernel cannot change syscall numbers. It will break their customer's software. Arch Linux doesn't really have "customers" in this sense, so they're free to play. The serious distros aren't.

Just mark my words: python 3 will never be a default "python". We're entering year 4 of the python3 era. You really think anyone's going to jump now if they haven't already?


>Doesn't seem like the author really thought some of this through

Yeah, he says the same thing at the bottom:

>Poul-Henning

I guess it would be nice if he warned you up front, but at least he does include the warning.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: