I am learning C: a little problem with a simple source code

T

Tim Rentsch

Keith Thompson said:
I stated my reasons several months ago.

Okay, let's review those. Here are all the relevant excerpts
I could find from all of your messages in this thread:

My own preference would have been to make defining "main"
incorrectly a constraint violation, not undefined behavior.

Obviously just a statement of personal opinion.
Programs using "void main(void)" (as well as books that claim
it's valid), would have been weeded out over the years as they
failed to compile.

That is a benefit (and granting FTSOD that the part about books
is also true, which I'm not as sure about, but no matter). I've
already agreed that some benefits exist, just have a different
opinion than yours as to their value.
But the fact remains that the language is defined the way it is,
and conforming to that definition shouldn't be at all difficult.

It isn't clear whether this is talking about the current standard
or the hypothetical revised one (where non-working forms of main()
have mandatory diagnostics), but in any case all that's being offered
is opinion.
Failing to do so can *sometimes* indicate a lack of attention to
detail that can and should reduce the reader's trust in the rest
of the code (Schildt's books are a classic example).

That's a true statement (not counting the 'should' part, which is
a judgment call), but it isn't by itself an argument that such
cases of main() should be made constraint violations.
Yes, I'm assuming that a given compiler knows what forms of main
are supported by that compiler. That's not *necessarily* true;
the same compiler could be used both for a target that supports
"double main(char*)" and for one that doesn't. In effect, the
same compiler would be part of two distinct implementations.

But in such a case, it shouldn't be at all difficult to
parameterize the compiler so that it *does* know what forms of
main are supported.
Opinion.

There's no reason a single compiler can't
produce different diagnostics when invoked for different targets.

Obviously it can, but forcing that approach also has costs,
as I have already mentioned.
I also want diagnostics for syntax errors, missing headers,
undeclared identifiers, and so forth. These diagnostics are
required by the language, and I presume you don't object to that.

I fail to see how using a definition of main *that is not
supported by the compiler I'm using* should be any different.

This is a point of argument, but a weak one. I've already
responded to this statement, pointing out some differences.
But if you don't want such a warning, you could always filter
it out or invoke the compiler in some non-conforming mode.

I would call this a rhetorical argument: it's the sort of
argument that often works in debate-like settings but on closer
examination doesn't have much substance; my response earlier
explains this more specifically.
It would be helpful if you could cite a specific implementation
where this [knowing what forms of main() won't produce bad
behavior] would be at all difficult. I've never encountered one.

The last sentence does make a point of sorts, but a weak one. I've
never seen a Higgs boson either, but that doesn't mean they don't
exist (and in fact they probably do even though no one has yet seen
any definite evidence for them). The posting from Philip Lantz
describes a particular multi-targeted implementation that's related
to this point.

Besides the statements of opinion, all I see are non-arguments
or weak arguments, all of which I've already responded to.

Continuing back at the last message...

This isn't important enough for me to spend any more time arguing
about it.

My point was that you aren't really offering much in way
of argument but just repeated statements of opinion. Every
point you've presented that counts even as a weak argument
I've already responded to. Conversely however, I have presented
several arguments to the contrary, and you have responded only
to some of them.
Your claim, that it can be difficult for a compiler to determine
what forms of main() it should support, is an interesting one.
As I said, I've never encountered such a situation. I was hoping
both to learn something and to advance this discussion.

I understand that it's theoretically possible that a compiler might
have difficulty determining what forms of main() are supported on the
target system for which it's generating code. I do not believe that
there is any such difficulty in practice.

Have you ever tried doing it? Not just finding out what the
possibilities are, but writing the code that diagnoses them?
And, after that, tried maintaining those implementations as
the operating system(s) that they support evolve and accommodate
or disaccommodate various forms of main() that work (needless to
say, without bothering to notify all the compiler developers
in the world)? The statement would be a lot more convincing
if it were backed up by some experience actually doing it,
rather than just a gedanken experiment.

I'll just leave it at that.

(What I *really* would have preferred would be for any definition of
main() other than the two standard ones to be a constraint violation.
Compilers could still support other forms as an extension and/or in
some non-conforming mode. That *might* have prevented the endless
arguments over "void main()", with no great cost that I can see.
I know about the third "envp" parameter; as I said, that could still
be implemented, but with a diagnostic or in non-conforming mode.
To be clear, I'm talking about a hypothetical change that *could*
have been made by ANSI in 1989, and that would apply only to hosted
implementations.)

So you were only kidding when you said "I'll just leave it
at that."?
 
P

Philip Lantz

Keith said:
When you say you use the exact same GCC, does that imply that you could
take an object file generated by the GCC you're using and use it either
on the Linux platform or on the embedded system? If so, that's not what
I would have expected.

Yes. I'm not sure I've ever done this, so I can't swear that there
aren't differences in compiler invocation that would make the object
files incompatible, but I don't think that there are; and if there were
any reason to share object files between the two, I think it could be
done without much effort.

Philip
 
K

Keith Thompson

Philip Lantz said:
Yes. I'm not sure I've ever done this, so I can't swear that there
aren't differences in compiler invocation that would make the object
files incompatible, but I don't think that there are; and if there were
any reason to share object files between the two, I think it could be
done without much effort.

Interesting.

Then that would be a valid case where it could be difficult for
a compiler to warn about an unsupported definition of main().
I suppose it could still be checked at link time, but requiring
that might be a but much.

That would be the only excuse I can think of for not warning about
a definition of main() that's not supported on the current system.

As I think I mentioned elsethread, gcc warns about "void main(void)",
at least on my system. Does your embedded target permit "void
main(void)", and does gcc (incorrectly) warn you about it when you
compile for it?
 
P

Philip Lantz

Keith said:
Interesting.

Then that would be a valid case where it could be difficult for
a compiler to warn about an unsupported definition of main().
I suppose it could still be checked at link time, but requiring
that might be a but much.

That would be the only excuse I can think of for not warning about
a definition of main() that's not supported on the current system.

As I think I mentioned elsethread, gcc warns about "void main(void)",
at least on my system. Does your embedded target permit "void
main(void)", and does gcc (incorrectly) warn you about it when you
compile for it?

Yes, and yes. And I have a confession to make. Having now gone back and
looked at the code, I realize that my original post was misleading (some
might say out-and-out false), because the main function that is called
by the assembly startup code is not, in fact, called "main". I don't
know why we named it something else; it could be because of this GCC
warning. However, it would not be unreasonable of you to retract your
acceptance of this as a valid counter-case.

Philip
 
R

Robert Miles

I use GCC to generate code for both a standard Linux platform, and for
an embedded system. I use the exact same GCC for both cases. In the
latter case, main is called by startup code that I have written in
assembly language. GCC has *no idea whatsoever* what forms of main will
work and which will cause undefined behavior. I doubt very much that
this is an uncommon situation. How do you think GCC could be made to
issue the warning that you suggest should be required?

In that case, I'd expect gcc to have a way to tell it which target
to compile for, although with some default in case you don't tell
it (probably the same type of machine you are running gcc on).

Any well-written compiler should know which forms of main that
compiler supports, even if it needs to know the target to tell
which forms the target supports.
 
N

Nomen Nescio

gcc blows and so do all FSF homo fanboys


Robert Miles said:
In that case, I'd expect gcc to have a way to tell it which target
to compile for, although with some default in case you don't tell
it (probably the same type of machine you are running gcc on).

Any well-written compiler should know which forms of main that
compiler supports, even if it needs to know the target to tell
which forms the target supports.
 
P

Philip Lantz

Robert said:
In that case, I'd expect gcc to have a way to tell it which target
to compile for, although with some default in case you don't tell
it (probably the same type of machine you are running gcc on).

Any well-written compiler should know which forms of main that
compiler supports, even if it needs to know the target to tell
which forms the target supports.

The compiler doesn't support--or fail to support--any form of main. The
compiler doesn't have anything to do with the form of main that is
supported, and furthermore, absent this proposed warning, it doesn't
care.

How can the compiler possibly know what form of main is supported by my
embedded system? I can construct an embedded system that uses any
conceivable form of main. The only way would be to use a function
declaration to specify it. Oh, wait, that's what we already do!
 
8

88888 Dihedral

Tim Rentschæ–¼ 2012å¹´2月1日星期三UTC+8下åˆ1時46分40秒寫é“:
No, the rules for main() are different; that's why they
are described separately.

In C functions are distinguished by names not including parameters.

In some other computer languages, functions are resolved including
parameters.

Both approaches can work well.

If <hdr1.h> and <hdr2.h> are both included in the same
translation unit, a diagnostic must be issued.

If not, I'm still okay with a compiler giving a warning,
especially if there is an option to turn it on or off.
However, saying _a_ compiler _may_ give a warning is very
different from saying _all_ compilers _must_ give a warning.

Moreover, the point for main() is that often we do _not_
know which forms will cause errors and which ones will not.
Furthermore, even if there were an known problem with
form X on platform P, there still is value in allowing
it to be accepted on platform P, because form X may be
perfectly acceptable on platform Q, and all I'm doing is
a test compile.

In short, I'm not opposed to the idea of having a warning
for main(), just opposed to the idea that such a warning be
required at all times for all C compilers.

The function main() is just an entry point in C.

Nowadays event and message driven programs that behave like those using theIRQ and BIOS services in the HW and OS are very common in applications.

But I have to say the application part is different from the services in the
design.

The OS part requires more disciplines in programming.
 
T

Tim Rentsch

Robert Miles said:
I use GCC to generate code for both a standard Linux platform, and for
an embedded system. I use the exact same GCC for both cases. In the
latter case, main is called by startup code that I have written in
assembly language. GCC has *no idea whatsoever* what forms of main will
work and which will cause undefined behavior. I doubt very much that
this is an uncommon situation. How do you think GCC could be made to
issue the warning that you suggest should be required?

In that case, I'd expect gcc to have a way to tell it which target
to compile for, although with some default in case you don't tell
it (probably the same type of machine you are running gcc on).

Any well-written compiler should know which forms of main that
compiler supports, [snip].

That suggestion is exactly the issue under contention. Simply
asserting that it is true doesn't make it true. Or are you
offering only an opinion?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,079
Messages
2,570,574
Members
47,207
Latest member
HelenaCani

Latest Threads

Top