There are some very experienced folks on Stack Overflow who always talk about the C standard. People seem to not like non-portable solutions, even if they work for me. Ok, I understand that the standard needs to be followed, but doesn't it put shackles on programmer's creativity?

What are the concrete benefits that come from following a standard? Especially since compilers may implement the standard slightly differently.

  • 7
    Could you clarify what you mean by "the standard"? Do you mean not realying on behaviour that is not defined by the standard? Or not using extensions / compiler features? Or style conventions? – ikh Jul 20 '13 at 17:49
  • 1
    @ikh He is taking about ISO C standards(C90, C99, C11). – Aseem Bansal Jul 20 '13 at 17:53
  • 9
    That's the same as saying that writing or speaking in English, using English grammar and vocabulary, puts shackles on your creativity. Sure, people can do wonderful things by breaking the rules, at the cost of coherence, but you can write millions of creative books while still adhering to the "standard" of English. – Avner Shahar-Kashtan Jul 20 '13 at 19:04
  • can you add an example of "People seem to not like non-portable solutions, even if they work for me"? – BЈовић Jul 20 '13 at 21:11
  • 1
    @PHIfounder Just to address that last case, you can omit the return from main, it's implicitly return 0 :) – jozefg Jul 21 '13 at 13:12

There are a few reasons why sticking to the standard is a good thing.

  1. Being locked into a compiler sucks hard. You're completely at the mercy of a group of developers with their own agenda. They're obviously not out to get you or anything, but if your compiler starts lagging on optimizations, new features, security fixes etc, too bad; You're stuck. In extreme cases some companies have to start patching whatever tool they have made themselves dependent on. This is a huge waste of money and time when there are other working tools out there.

  2. Being locked into a platform sucks harder. If you're pushing software on Linux and and want to switch to Windows because you realize your market is really there, you're gonna have a heck of a time changing every non-portable hack you've got in your code to play nice with both GCC and MSVC. If you've got several pieces of your core design based around something like that, good luck!

  3. Backward incompatible changes sucks the hardest. The standard will never break your code (Ignore python). Some random compiler writer though might decide that really this implementation specific add-on is not worth the trouble and drop it. If you happen to rely on it, then you're stuck on whatever old outdated version it was last in.

So the overriding message here, sticking to the standard makes you more flexible. You have a more limited language sure, but you have more

  • Libraries
  • Support (people know the standard, not every intricate compiler-specific hack)
  • Available platforms
  • Mature tools
  • Security (future proofness)

It's a delicate balance, but completely ignoring the standard is definitely a mistake. I tend to organize my C code to rely on abstractions that might be implemented in a non-portable way, but that I can transparently port without changing everything that depends on the abstraction.

  • +1 fair enough :) , thanks ... I was seriously confused the way compilers deviated slightly from the standards and made me feel skeptical about strictly following it , needed to know the pros and cons of it and you clearly identified those . – 0decimal0 Jul 21 '13 at 4:33
  • 6
    Undefined behavior probably sucks quite a bit as well. With c it's pretty easy to venture into UB if you don't follow the standard closely. – CodesInChaos Jul 21 '13 at 9:32
  • @CodesInChaos Agreed, undefined behavior is great on one hand since it allows for some crazy optimizations, but on the other debugging it... – jozefg Jul 21 '13 at 15:13

The standard is a sort of "contract" between you and your compiler that defines the meaning of your programs. As programmers, we often have a certain mental model of how the language works, and this mental model is often at odds with the standard. (For example, C programmers often think of a pointer as roughly "an integer that denotes a memory address", and therefore assume that it's safe to perform any arithmetic/conversions/manipulations on pointers that one might perform with an integer that denotes a memory address. This assumption does not agree with the standard; it actually imposes very strict restrictions on what you can do with pointers.)

So, what's the advantage of following the standard, rather than your own mental model?

Simply put, it's that the standard is correct, and your own mental model is wrong. Your mental model is typically a simplified view of how things work on your own system, in common cases, with all compiler optimizations disabled; compiler vendors do not generally make an effort to conform to it, especially when it comes to optimizations. (If you don't hold up your end of the contract, you can't expect any specific behavior from the compiler: garbage in, garbage out.)

People seem to not like non-portable solutions, even if they work for me.

It might be better to say, "even if they seem to work for me". Unless your compiler specifically documents that a given behavior will work (that is: unless you're using an enriched standard, consisting of the standard proper plus compiler documentation), you don't know that it really works, or that it's really reliable. For example, signed integer overflow typically results in wrapping on many systems (so, INT_MAX+1 is typically INT_MIN) — except that compilers "know" that signed integer arithmetic never overflows in a (correct) C program, and often perform very surprising optimizations based on this "knowledge".

  • 1
    You could compile with -fwrapv, and then you're using a slightly different, non-standard language where signed integer arithmetic always wraps. – immibis Jul 26 '14 at 3:48
  • @immibis: When C89 was written, according to its rationale document, the majority of contemporary compilers defined silent wrapping semantics for integer overflow. In many cases, having some sorts of guarantees about what happens in case of integer overflow may allow code to be more efficient than would be possible without such guarantees, especially if the guarantees don't go so far as to mandate precise wrapping behavior [precise wrapping behavior could be emulated using unsigned math, but semantics which are looser but still adequate to meet requirements may allow more efficient code]. – supercat Apr 21 '16 at 19:19
  • @immibis: It's too bad that revisionists have been able to convince people that behaviors which were implemented nearly unanimously among compilers for certain platforms (or in some cases 100% unanimously) have never been "standard" on such platforms, since in many cases the loss of efficiency resulting from having to avoid such behaviors will not be recouped by any "optimizations" that a compiler was able to achieve by revoking them. – supercat Apr 21 '16 at 19:22

I understand that the standard needs to be followed , but doesn't it put shackles on programmer's creativity? there are still some differences in the way different compilers follow the standards. I can for example write a code which works, very good in performance and speed i.e, all that matters, but still that may not necessarily strictly follow the standards.

No. The standard tells what is allowed to do. If it is not specified, you are in undefined behaviour territory, and then all bets are off - the program is free to do anything.

Since you mentioned specific example of void main() vs int main(), I can improve my answer.

void main() is not a standard declaration of the main function. It may work on some compilers through extensions, but it rely on the implementation. Even if it works, you have to check if it does what you want. The problem is, compiler developers may decide to remove void main() with next compiler release, breaking your application.

On the other hand, the standard clearly defines the signature of main as int main() and it tells what it should do.

On the other hand, there are things not defined in the standard. Then, another standard may apply (like for example, POSIX). The best example may be with threads implementation in c++03, since c++03 standard programs were 1-threaded. In that case, you are forced to use platform dependent library, or something like boost.

  • 4
    Everything a compiler does that isn't standard isn't undefined behavior, compiler extensions are well defined in the sense that they are deterministic and deliberate. UB isn't. – jozefg Jul 20 '13 at 18:30
  • @jozefg The way it was asked - it is obvious that the OP thought of UB way of implementing. For example, threads were not defined in c++03. – BЈовић Jul 20 '13 at 18:44
  • 1
    @deworde: The comment was removed from the answer. – Kevin Jul 26 '13 at 18:39
  • @jozefg If a particular compiler always wraps signed integers, it could be considered an undocumented language extension. (Of course, being undocumented means you have no guarantees about them not removing the extension) – immibis Apr 21 '16 at 20:42

Don't follow rules IF your project is about special projects, for example a gov project or army one, but you need to follow rules IF you are talking about an open source or large project with a distributed team.

  • 2
    without an explanation, this answer may become useless in case if someone else posts an opposite opinion. For example, if someone posts a claim like "follow rules IF your project is about special projects, for example a gov project or army one, but you don't need to follow rules IF you are talking about an open source...", how would this answer help reader to pick of two opposing opinions? Consider editing it into a better shape – gnat Jul 21 '13 at 13:52
  • 2
    Uknown: you'd be surprised to learn how many standards there are in gov projects... – Deer Hunter Jul 21 '13 at 17:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.