Ever look at old code and think? What the hell was I smoking?

Pages: 12345
I really don't understand the attacks on NoXzema I don't see where he has said anything that deserves this much attitude.
@SGH: actually I side with JLBorges. I didn't realize earlier what exactly the argument was about until it was clarified.
Last edited on
What's the clarification then, because I really can't see it.
I'm lost in this topic.
Last edited on
The clarification is the claim at hand, the counter argument, and which one stands up the most. I will state the claims again.

I claimed that C89 and C90 (which are essentially the same thing), allowed "void main" only by the fact that it does not have anything stating that it's not allowed. I'm not saying it's the most correct, I'm not saying it should be allowed, only that in C89/C90, it was not illegal to have a main function that had no return value.

Responses provided apparently include the standard's provided examples. I claimed that the examples are just that, examples. They shouldn't provide every use case nor do any other examples in the standard do so.

Another response is Bjorne Stroustrup's claim that void main was never in the standard. He's correct. It never was since it's implementation defined. However, he claims that ISO C states that a required type of int is required for ISO C, which I can only imagine is meant in C99 given the date the article was made since there is no wording supporting this.

Good Reading: http://www.eskimo.com/~scs/readings/voidmain.960823.html

I also question the reason why additional wording was required in later revisions to the standard if the original wording was adequate.

So, now that that's clarified, what's your opinion on the matter?
Anyways, I sometimes look at my old code and do a face palm. But I know what I was smoking (metaphorically). I can sort of remember what I was thinking and why I was thinking like that.

A) I was rushing,

B) I was up too late and burnt out,

C) I was still a beginner and had limited knowledge,

and or

D) I was too focused on the results and didn't care about the code.

E) Or I look at it and question my intelligence.

I always wonder what my classmates code looks like. Because homework is graded automatically, the instructor doesn't look at and comment on your code, essentially you are the only person at all who see's it. Well maybe the instructor might read it, but you would never know it if he did. You're not allowed to post it online or let another student see it. People don't really have a lot of time to learn how to write good code and it isn't really taught or tested on; most people just want to match the output of the tester and get their grade. I'm willing to bet that most people's code is pretty horrible and that most people graduate without ever learning how to write good code.
Last edited on
I guess you deserve the... "victory"?
I'll be out for a while.
n1, gg.
Responses provided apparently include the standard's provided examples. I claimed that the examples are just that, examples. They shouldn't provide every use case nor do any other examples in the standard do so.

They aren't examples. They're part of the normative text, which clearly states how they may differ from what is shown, and changing the return type is not mentioned.

Furthermore we can pop down to the last part of that section:

"Program termination"

A return from the initial call to the main function is equivalent to calling the exit function with the value returned by the main function as its argument. If the main function executes a return that specifies no value, the termination status returned to the host environment is undefined.


which indicates main will be returning a value, even if that value may be undefined. (Note that in C, returning from functions without returning a value, even though the function promised to return one, was (is?) perfectly legal as long as the return values were not used in the cases where they were not returned -- not having destructors makes that possible.)

Yes, clearly void main is allowed for a freestanding implementation in C89, but we don't generally characterize things that are allowed only as implementation-defined features to be legal/standard C or C++. If we did, it would be very confusing to speak of such things.

which indicates main will be returning a value, even if that value may be undefined. (Note that in C, returning from functions without returning a value, even though the function promised to return one, was (is?) perfectly legal as long as the return values were not used in the cases where they were not returned -- not having destruction makes that possible.


At least in x86-64, the register where the return value would be is where the calling code would look for the returned value. Of course there will always be something there, but if you hadn't returned something, then you would not have placed anything in that register, hence it's value would not be defined.

That quote doesn't say anywhere that the function will return a value, only that the termination status will be undefined. Again I am considering "returning" a value as purposefully placing a value in that register before returning. The fact that the value is undefined seams to indicate that nothing is placed in the register with the intent on it being the return value.

I'm not saying I know what I'm talking about, but this is what it would seam to me.

Then again I have no idea what takes place in other systems but one example is sufficient to prove my point.

Anyways, there is a difference between illegal and implementation defined. If the standard said it were illegal, then it would be illegal for all implementations conforming to the standard. I don't think it seams this is the case considering the evidence that has been presented. It seams pretty clear that the intention of the wording was to allow alternative implementations to define the signature of the main function beyond it's name. Those implementations which otherwise follow the requirements are conformant to the standard and legal.
Last edited on
The catch is that exit's parameter type is well defined.
Okay so I read around in GNU GCC's documentation:
The original ANSI C standard (X3.159-1989) was ratified in 1989 and published in 1990. This standard was ratified as an ISO standard (ISO/IEC 9899:1990) later in 1990. There were no technical differences between these publications, although the sections of the ANSI standard were renumbered and became clauses in the ISO standard. This standard, in both its forms, is commonly known as C89, or occasionally as C90, from the dates of ratification. The ANSI standard, but not the ISO standard, also came with a Rationale document.To select this standard in GCC, use one of the options -ansi, -std=c90 or -std=iso9899:1990; to obtain all the diagnostics required by the standard, you should also specify -pedantic (or -pedantic-errors if you want them to be errors rather than warnings).


A file with void main in it compiled with those options:

gcc -c mainT.c -ansi -pedantic

Gives:

mainT.c:1:6: warning: return type of ‘main’ is not ‘int’ [-Wmain]
 void main()
      ^

Meaning that even in C89, void main was illegal in regards to the standard.
Last edited on
I honestly have half a mind to file a bug report and see the response I get...
Meaning that even in C89, void main was illegal in regards to the standard.

But that is just what gcc says.

Try this and you get no warnings.

gcc -ffreestanding -ansi -pedantic test.c

freestanding enviroment is a special clause in standard to define what parts of standard C compilers for microcontrollers should comply and what they can ignore because their enviroment lacks some vital parts which is assumed to exist in hosted enviroment (like OS).

So if you are writing something which should work independetly of C standard library and OS (like bootloader or BIOS) you can use freestanding enviroment and dont even have main() in your program. Otherwise you should comply to standard and have int main.
To say that using void main() is legal in C is like saying that killing people is non-punishable: it is, in some specific curcumstances (embedded programming/some cases of self-defense)
Looking at the revisions and the minor changes to the section, taking it as a whole. It doesn't come across as they allowed it and then didn't. It looks more like they are saying, "well we had the examples of int main and even said implementations could offer more options, but apparently no one could figure it out so we have to spell it out for them. main has to return an int, implementation can do their variants, but it won't conform to the standard."
So in conclusion:
1) void main() is legal in freestanding environments
("custom" main()'s and the complete absence of main() are legal too)
2) void main() is not legal in hosted environments
3) void main() was made "legal" by compiler implementers because their clients wanted that
(but remains non-standard for hosted environments, though)
The terms 'legal' and 'illegal' do not make sense in this context: the analogy with killing people is singularly inappropriate.

For instance, there is no legality involved in 'undefined behaviour' - it simply means that the standard has nothing to say (imposes absolutely no requirement) on the observable behaviour of the program.

My reading of the C89 standard is:
a. Every conforming hosted implementation must support
int main(void) { /* ... */ } and int main(int argc, char *argv[]) { /* ... */ } or their equivalent forms.

b. A conforming hosted implementation is allowed to support additional forms of main().
For instance int main(int argc, char *argv[], char *envp[] ) is commonly supported; supporting such a main() does not make an implementation non-conforming. However, the standard does not require that any alternate form of main must be supported.

C99 makes it explicit that all forms of main() must be defined with a return type of int. In C89, it has to be inferred (and arguably, is subject to interpretation).

c. In particular, there is no requirement that void main() must be diagnosed and a diagnostic must be issued by a conforming hosted implementation. A particular implementation may silently accept void main() and the program may either crash or proceed normally, another may issue a warning diagnostic, yet another may treat the program as ill-formed - all three would still be conforming implementations.

What C89 specified 25 years ago is now a mere historical curiosity; C90 was corrected with two technical corrigenda (1994,1996) and an amendment (1995) and was finally superseded in 1999. IMHO, the topic is not worthy of such an extended and impassioned debate.
ANSI C is still rather widely used, especially since VC++ still doesn't fully support C99 let alone C11. Of course, whether or not you should use void main is obvious. I wasn't a programmer from 1989, I don't know what a common calling environment expected back then.

Still, I only feel justified that at least a good bit of the C community in the 90s used void main() under the assumption it was allowed. If the interpretation was so obviously in one direction, I'm not so sure there would have been such a confusion.

On another note, they could have just had void main return a default to 0...
I find it hilarious that MSVC doesn't yet support C99 and yet they are implementing features of C++11 and even C++14, all with incomplete support of course.
Read their many posts on the subject and that will help explain why they are doing so. I don't have experience in compiler development or language development but from what I have read it isn't just go down a list of features to implement then move on to the next standard. Some things are considerably harder to implement and provide little benefit overall while others are much easier to implement and provide major benefit.

While I would like to have full C++11and C99 compliance in MCVS I can see why they are doing it the way they are and really haven't been affected personally by not having a few minor features supported
Last edited on
Some things are considerably harder to implement and provide little benefit overall while others are much easier to implement and provide major benefit.

Some things are harder than others, but if they are not all there, the compiler is useless: it won't compile existing C programs.

All other vendors I've used support all or almost all of C99 since many years ago, and are moving towards C11 compliance today. Millions of lines of C in my company alone has been written that work with IBM, Oracle, HP, and GNU compilers (not sure if Intel was used for that codebase, but they are good with c99 too). Microsoft would choke on every file.

Granted, not every vendor implemented every single bullet point: people pretty much learned to live without the FENV_ACCESS pragma in portable C, but until Microsoft gets anywhere remotely close to the subset of C99 that everyone else uses, I don't consider them to be a C compiler vendor at all.
Pages: 12345