Topic: Void main() -- 3 Type of `main


Author: kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763)
Date: 1995/06/13
Raw View
In article <3rh2h7$7ot@silver.jba.co.uk> JdeBP@jba.co.uk (Jonathan de
Boyne Pollard) writes:

|> : |> --------------------------------------------------------------------------
|> : |> 2  This function is not predefined by the implementation.  The set of
|> : |>    definitions for main that are acceptable (and thus by implication the
|> : |>    type of main) is implementation defined, and main cannot be [...]
|> : |>    overloaded.  All implementations must include the definitions
|> : |>            int main () { /* ... */ }
|> : |>    and
|> : |>            int main (int, char *[]) { /* ... */ }
|> : |>    in that set, but are free to extend the set with additional function[...]
|> : |> --------------------------------------------------------------------------

|> : I'm sorry.  I misinterpreted your text, by cutting the sentence "All
|> : implementations must include the definitions..." immediately after the
|> : examples.  My comments were based on that misinterpretation.

|> Ah, perhaps :

|> --------------------------------------------------------------------------
|> 2  This function is not predefined by the implementation.  The set of
|>    definitions for main that are acceptable (and thus by implication the
|>    type of main) is implementation defined, and main cannot be overloaded.
|>    The definitions
|>            int main () { /* ... */ }
|>    and
|>            int main (int, char *[]) { /* ... */ }
|>    must be included in that set by all implementations, but implementations
|>    are free to extend the set with additional function types [...]
|> --------------------------------------------------------------------------

|> would be clearer ?

Perhaps.  Reading the original when one is less tired helps, too:-).
--
James Kanze         Tel.: (+33) 88 14 49 00        email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils en informatique industrielle --
                              -- Beratung in industrieller Datenverarbeitung







Author: JdeBP@jba.co.uk (Jonathan de Boyne Pollard)
Date: 1995/06/12
Raw View
James Kanze US/ESC 60/3/141 #40763 (kanze@lts.sel.alcatel.de) wrote:
: My own point of view is that this specificity is best described by
: saying that main has a special (implementation-defined) type.  An
: implementation must accept a certain number of definitions (and why
: not, a certain number of declarations) as conforming to that type.
: (In this regard, I am probably influenced by the use of compatible
: types in the C standard.  The user-provided definition must be of a
: type compatible to the type of main.  This is not the wording of the
: current standard, however.)
:
: If I understand your point of view correctly, you think that main is
: best described as having the type which the user defines.  It is
: special in a number of (type independant) ways, and there is a finite
: set of types which the compiler will accept.

I think that that is a fair summary of both our positions.


: To be very clear, we are talking about how to describe the external
: behavior of the implementation (what programs it will/will not
: accept), and not the internal details.

Exactly.

:                                        In practice, I would probably
: maintain an internal `main-function' type (as I would an internal null
: pointer type), even to implement your description of main.  However,
: maintaining main as the type defined by the user would be a valid
: implementation, even for my description, as long as the compiler was
: able to recognize main as a special case (e.g.: to prevent calling it
: or taking its address) by some other means.

As far as I'm concerned, `main' should have as few "special" user-visible
semantics as possible when compared to other C++ functions, therefore the
type of `main' should be considered to be the function type that the
programmer uses in the function definition.

Although an implementation should be free to do whatever internal symbol
table magic as necessary (and, indeed, part of the reason that I would have
liked to have prohibited declarations of `main' outside of its definition
is to give implementations as much freedom as possible with magic internal
symbol table stuff) the draft should talk of the type of `main' in terms of
the user-visible function type, and not introduce the concept of a special
"magic" type, especially since such a "magic" type would necessarily have
to be *not* expressible in terms of the C++ language.

: Given my point of view, I find the current wording of the standard (in
: this section) quite acceptable.  Although I can understand your point
: of view, and it is probably closer to what most people instinctively
: feel, I do not feel that there is any real problem with the standard
: in this section, and certainly not enough problem to be worth any
: effort on my part.  On the other hand, if you feel differently, and
: are willing to invest the effort...  I do not feel the issue important
: enough to oppose you.

Well, I find the current version of the draft ambiguous and deficient with
respect to some of the semantics that distinguish `main' from all other
functions.  I do think that [basic.start.main] needs a little touching up.

With reference to the current thread (the type of `main') I still think
that the standard should be clearer that the type of `main' used in any
program may be chosen from an implementation-defined set, rather than
saying that the (*single*) type of `main' is implementation-defined
and then going on to give two alternative types for it.

: |> --------------------------------------------------------------------------
: |> 2  This function is not predefined by the implementation.  The set of
: |>    definitions for main that are acceptable (and thus by implication the
: |>    type of main) is implementation defined, and main cannot be [...]
: |>    overloaded.  All implementations must include the definitions
: |>            int main () { /* ... */ }
: |>    and
: |>            int main (int, char *[]) { /* ... */ }
: |>    in that set, but are free to extend the set with additional function[...]
: |> --------------------------------------------------------------------------

: I'm sorry.  I misinterpreted your text, by cutting the sentence "All
: implementations must include the definitions..." immediately after the
: examples.  My comments were based on that misinterpretation.

Ah, perhaps :

--------------------------------------------------------------------------
2  This function is not predefined by the implementation.  The set of
   definitions for main that are acceptable (and thus by implication the
   type of main) is implementation defined, and main cannot be overloaded.
   The definitions
           int main () { /* ... */ }
   and
           int main (int, char *[]) { /* ... */ }
   must be included in that set by all implementations, but implementations
   are free to extend the set with additional function types [...]
--------------------------------------------------------------------------

would be clearer ?





Author: kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763)
Date: 1995/06/09
Raw View
In article <3r7nrb$549@silver.jba.co.uk> JdeBP@jba.co.uk (Jonathan de
Boyne Pollard) writes:

|> James Kanze US/ESC 60/3/141 #40763 (kanze@lts.sel.alcatel.de) wrote:
|> : In article <3r5j8f$ffv@silver.jba.co.uk> JdeBP@jba.co.uk (Jonathan de
|> : Boyne Pollard) writes:

    [much discussion concerning main deleted...]

I think we are arguing over how many angels can dance on the head of a
pin.  We (and I think everyone else) agree that the function main is
special, and requires special handling by the compiler.

My own point of view is that this specificity is best described by
saying that main has a special (implementation-defined) type.  An
implementation must accept a certain number of definitions (and why
not, a certain number of declarations) as conforming to that type.
(In this regard, I am probably influenced by the use of compatible
types in the C standard.  The user-provided definition must be of a
type compatible to the type of main.  This is not the wording of the
current standard, however.)

If I understand your point of view correctly, you think that main is
best described as having the type which the user defines.  It is
special in a number of (type independant) ways, and there is a finite
set of types which the compiler will accept.

To be very clear, we are talking about how to describe the external
behavior of the implementation (what programs it will/will not
accept), and not the internal details.  In practice, I would probably
maintain an internal `main-function' type (as I would an internal null
pointer type), even to implement your description of main.  However,
maintaining main as the type defined by the user would be a valid
implementation, even for my description, as long as the compiler was
able to recognize main as a special case (e.g.: to prevent calling it
or taking its address) by some other means.

Given my point of view, I find the current wording of the standard (in
this section) quite acceptable.  Although I can understand your point
of view, and it is probably closer to what most people instinctively
feel, I do not feel that there is any real problem with the standard
in this section, and certainly not enough problem to be worth any
effort on my part.  On the other hand, if you feel differently, and
are willing to invest the effort...  I do not feel the issue important
enough to oppose you.

|> : Your wording is defective in two regards:
|> :
|> : 1. It says that the implementation must include definitions for main.
|> : In fact, the *implementation* is forbidden from defining main.
|> :
|> : 2. It suggests that there are a set of definitions, i.e.: more than
|> : one.  In fact, `main' must have one and only one definition.

|> Again wrong.  Here is the relevant part of my suggestion :

|> --------------------------------------------------------------------------
|> 2  This function is not predefined by the implementation.  The set of
|>    definitions for main that are acceptable (and thus by implication the
|>    type of main) is implementation defined, and main cannot be [...]

[Here I add some of the elided text...]

|>    overloaded.  All implementations must include the definitions
|>            int main () { /* ... */ }
|>    and
|>            int main (int, char *[]) { /* ... */ }
|>    in that set, but are free to extend the set with additional function[...]
|> --------------------------------------------------------------------------

I'm sorry.  I misinterpreted your text, by cutting the sentence "All
implementations must include the definitions..." immediately after the
examples.  My comments were based on that misinterpretation.

As it stands, I have no particular objections to your text; if it had
been the initial text, I wouldn't be fighting to change it.  But I
find the current text adequate, and see no need for additional effort
here.
--
James Kanze         Tel.: (+33) 88 14 49 00        email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils en informatique industrielle --
                              -- Beratung in industrieller Datenverarbeitung







Author: JdeBP@jba.co.uk (Jonathan de Boyne Pollard)
Date: 1995/06/09
Raw View
Christian Millour (chris@alofi.etca.fr) wrote:
: In article <3r7lli$4no@silver.jba.co.uk>, JdeBP@jba.co.uk
: (Jonathan de Boyne Pollard) writes:
: |> Steve Clamage (clamage@Eng.Sun.COM) wrote:
: |>
: |> : I didn't see any use for declaring main in C++ until someone (sorry,
: |> : I forget who) suggested you might want to make main a friend of some
: |> : class. I see no reason to prohibit that.
: |>
: |> I saw that too.  A pity.
:
: For the record, I merely answered Steve's interrogation (why would you
: want to declare main ?) by providing an example out of published code.
: I'm certainly not endorsing the quoted practice.

Certainly.  But it still means (as Steve Clamage said) that people may have
a legitimate need to declare `main' for such purposes as making it a friend
of a class.

( This seems to be contrary to the principle of data hiding, and it would IMO
have been better to have made the Initialise() function member in that code
that you posted part of the public interface, rather than grant `main'
unconditional access to the private interface.  But that's an aside. )

I've given this some thought overnight, and I cannot come up with a means
of allowing `main' to be a friend declaration without it also being
allowable as an ordinary declaration.

Which concentrates the problem nicely.  Do we prohibit the declaration of
`main' outside its definition and gain the dual advantages of allowing
implementations to perform internal symbol table magic on `main' and
preventing the programmer from being *able* to call `main' or take its
address ?  Or do we allow declarations of `main' outside of its definition,
and allow people to use it in friend declarations ?

:                                                   IMHO the existence of
: such code demands that the issue of main's declarability (including as
: a friend) be explicitely addressed in the standard.

I think that you have an important point there.  Either way we jump, the
draft needs to say *something*.

:                                                     I find your rewording
:
: 3  ... The function main shall not be declared except at its definition ...
:
: reasonable but AFAIK some developpers might have different needs (imbedded
: apps maybe ?).

Possibly.  But all that we have to build on is the existing draft, which
doesn't make any exemptions in [basic.start.main] for freestanding
implementations, which I assume means that programs compiled on freestanding
implementations must have `main' in all its glory, as well.

Aside from friend declarations, are there any other uses to which a
declaration of `main' outside of its definition may be put ?  Offhand it
seems that the only other two are to call it (which is prohibited anyway)
and to take its address (which is also prohibited).  I cannot offhand think
of anything else that affects the issue one way or another.

: So, what's next ? Should I make contact with my national body, sending
: a copy of your suggestion, or should your own submission be enough ?

I think that the principle here is "the more, the merrier".  The more
people that put this forward to their national standards bodies, the more
likely they are to take in on board and forward it on to ISO.  The more
national standards bodies that submit it to ISO, the more likely it is to be
seriously considered for inclusion in the draft.

So, as I said in a previous message to another here, if you think that the
proposal holds water, then *yes* please submit it to your national
standards body.

( This also means that you aren't relying on my (somewhat shakey) contact
with people at BSI.  (-:  )





Author: kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763)
Date: 1995/06/08
Raw View
In article <3r5j8f$ffv@silver.jba.co.uk> JdeBP@jba.co.uk (Jonathan de
Boyne Pollard) writes:

|> James Kanze US/ESC 60/3/141 #40763 (kanze@lts.sel.alcatel.de) wrote:
|> : In article <3r2a91$m5g@silver.jba.co.uk> JdeBP@jba.co.uk (Jonathan de
|> : Boyne Pollard) writes:
|> : |> It is surely better to say that the implementation recognises a set of
|> : |> types for `main', at most one of which may be defined in any one program,
|> : |> which set must include at minimum the types `int main()' and `int main(int,
|> : |> char **)', and which set the implementation is free to extend.

|> : Except that I would expect that most implementations simply have a
|> : special type, main-function, which turns on all of the compiler magic.

|> I'm not sure what you mean by "main-function" here (that's certainly not
|> something that any C++ compiler that I can lay my hands on will accept as a
|> legal definition for the distinguished function `main'), and I suspect
|> a language barrier.

I mean a special type, used internally by the compiler.  In C, for
example, it is illegal to declare main, because there *is* no way in
the language to declare a function which can take either no
parameters, or two parameters.  Yet C compilers manage to cope.

In C++, all of the compilers I know of recognize the function main,
and treat it as a special case.  This could (and maybe does) include
using a special, compiler internal type, for the function.  (In all of
the cases I'm familiar with, for example, it also means turning of the
name mangling, even though the function is not declared to have "C"
linkage.)

In this sense, the type of main is sort of like the type of the null
pointer.  It may exist as a distinct type in the compiler, but there
is no way that you can write it in a program.

|> When I say "type for `main'" I mean type in the sense of "function type" as
|> defined in [dcl.fct].  Bearing this in mind it is apparent that the draft
|> *intends* that there is a set of function types that are acceptable in the
|> definition of `main', two of which are compulsory and must be accepted by all
|> implementations, and the remainder of which are defined by the
|> implementation.

|> ( Implementations that allow `int main(int, char **, char **)' and

And note that we have something very special here.  The type of main
must be such that both forms (plus any additional forms the compiler
accepts) match the function.

There is no way to write this in C++.  The compiler has to use some
sort of internal magic.  (A special internal type, or something else.)
|> `void main()' spring to mind. )

|> The problem is that whilst meaning to say this, it in fact says something
|> else by implying that `main' has *one* type (defined by the implementation)
|> and then contradicting itself by listing two types that all implementations
|> must accept.

Which means that internally, the compiler must recognize main as a
special case in one way or another.

|> Compare the current draft

|> --------------------------------------------------------------------------
|> 2 This function is not predefined by the implementation,  it  cannot  be
|>   overloaded,    and    its   type   is   implementation-defined.    All
|>   implementations shall allow both of the following definitions of
|>   main:
|>           int main() { /* ... */ }
|>   and
|>           int main(int argc, char* argv[]) { /* ... */ }
|> .
|> .
|> .
|>         [Note: It is recommended that any  further
|>   (optional) parameters be added after argv.  ]
|> --------------------------------------------------------------------------

|> with my suggested rewording

|> --------------------------------------------------------------------------
|> 2  This function is not predefined by the implementation.  The set of
|>    definitions for main that are acceptable (and thus by implication the
|>    type of main) is implementation defined, and main cannot be
|>    overloaded.  All implementations must include the definitions
|>            int main () { /* ... */ }
|>    and
|>            int main (int, char *[]) { /* ... */ }
|>    in that set, but are free to extend the set with additional function
|>    types. [ Note: It is recommended that implementations allow additional
|>    function types where the first two parameters are the same types and
|>    have the same semantics (see below) as those of the second definition
|>    above. ] [ Example: Implementations may allow definitions of main that
|>    do not return a value (i.e. void). ]
|> --------------------------------------------------------------------------

Well, the current draft is considerably clearer than your rewording.
It corresponds to the reality: `main' has *one*
(implementation-defined) type, regardless of how it is defined.

Your wording is defective in two regards:

1. It says that the implementation must include definitions for main.
In fact, the *implementation* is forbidden from defining main.

2. It suggests that there are a set of definitions, i.e.: more than
one.  In fact, `main' must have one and only one definition.

The one thing that I might change in the draft with regards to main is
to add the explicit injunction forbidding any declaration of main
(other than the definition).  This is already the case in C (if memory
serves me right), and I think that it is implicit in C++, since there
is in fact no way (or at the very least, no portable way) to declare
it without some sort of compiler magic (which has only been mandated
for the definition).
--
James Kanze         Tel.: (+33) 88 14 49 00        email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils en informatique industrielle --
                              -- Beratung in industrieller Datenverarbeitung







Author: JdeBP@jba.co.uk (Jonathan de Boyne Pollard)
Date: 1995/06/08
Raw View
James Kanze US/ESC 60/3/141 #40763 (kanze@lts.sel.alcatel.de) wrote:
: In article <3r2a91$m5g@silver.jba.co.uk> JdeBP@jba.co.uk (Jonathan de
: Boyne Pollard) writes:
: |> It is surely better to say that the implementation recognises a set of
: |> types for `main', at most one of which may be defined in any one program,
: |> which set must include at minimum the types `int main()' and `int main(int,
: |> char **)', and which set the implementation is free to extend.

: Except that I would expect that most implementations simply have a
: special type, main-function, which turns on all of the compiler magic.

I'm not sure what you mean by "main-function" here (that's certainly not
something that any C++ compiler that I can lay my hands on will accept as a
legal definition for the distinguished function `main'), and I suspect
a language barrier.

When I say "type for `main'" I mean type in the sense of "function type" as
defined in [dcl.fct].  Bearing this in mind it is apparent that the draft
*intends* that there is a set of function types that are acceptable in the
definition of `main', two of which are compulsory and must be accepted by all
implementations, and the remainder of which are defined by the
implementation.

( Implementations that allow `int main(int, char **, char **)' and
`void main()' spring to mind. )

The problem is that whilst meaning to say this, it in fact says something
else by implying that `main' has *one* type (defined by the implementation)
and then contradicting itself by listing two types that all implementations
must accept.

Compare the current draft

--------------------------------------------------------------------------
2 This function is not predefined by the implementation,  it  cannot  be
  overloaded,    and    its   type   is   implementation-defined.    All
  implementations shall allow both of the following definitions of
  main:
          int main() { /* ... */ }
  and
          int main(int argc, char* argv[]) { /* ... */ }
.
.
.
        [Note: It is recommended that any  further
  (optional) parameters be added after argv.  ]
--------------------------------------------------------------------------

with my suggested rewording

--------------------------------------------------------------------------
2  This function is not predefined by the implementation.  The set of
   definitions for main that are acceptable (and thus by implication the
   type of main) is implementation defined, and main cannot be
   overloaded.  All implementations must include the definitions
           int main () { /* ... */ }
   and
           int main (int, char *[]) { /* ... */ }
   in that set, but are free to extend the set with additional function
   types. [ Note: It is recommended that implementations allow additional
   function types where the first two parameters are the same types and
   have the same semantics (see below) as those of the second definition
   above. ] [ Example: Implementations may allow definitions of main that
   do not return a value (i.e. void). ]
--------------------------------------------------------------------------





Author: clamage@Eng.Sun.COM (Steve Clamage)
Date: 1995/06/08
Raw View
In article 95Jun8144749@slsvhdt.lts.sel.alcatel.de, kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763) writes:
>
>I mean a special type, used internally by the compiler.  In C, for
>example, it is illegal to declare main, because there *is* no way in
>the language to declare a function which can take either no
>parameters, or two parameters.  Yet C compilers manage to cope.

In C it is explicitly permitted to call main. I know of no rule against
declaring main. The C standard also mentions that implementations may
permit more than just the two mandated forms of main. A user declaration
of main would have to match the definition used in a particular program,
but you can have only one external function called "main" in a C (or
C++) program. I don't see any problem here.

The compiler (C or C++) has to figure out which use of the spelling "main"
is the program entry point. That isn't hard. If an entity called "main" has
external linkage and is a function (and in C++ is not a member of any class),
that's it. ("In the end, there can be only one.") The compiler could then
elect to allow only certain function types, and complain about, for example,
 double main(FILE*) { ... }
Or it might choose to allow anything the programmer wrote.

Perhaps you mean you can't write a declaration of main which will
survive incorporation in every program. That is true, since the
main function in another program might have a different type.

I don't see a need to prohibit declaring main.

In C, it is valid to call main, so it should be valid to declare it.
As with any function, declaration and definition must be compatible.

I didn't see any use for declaring main in C++ until someone (sorry,
I forget who) suggested you might want to make main a friend of some
class. I see no reason to prohibit that. (I don't see myself ever
writing such code, but that's a separate subject.) That the declaration
in the class must be compatible with the definition, that is no
different from the case for any other friend function.

---
Steve Clamage, stephen.clamage@eng.sun.com







Author: JdeBP@jba.co.uk (Jonathan de Boyne Pollard)
Date: 1995/06/08
Raw View
Steve Clamage (clamage@Eng.Sun.COM) wrote:
: I don't see a need to prohibit declaring main.

As I said in the original post, doing so allows implementors leeway to use
special symbol table magic to handle `main' by "pre-declaring" it, and
has the byproduct of preventing `main' from being called or its address being
taken.

: In C, it is valid to call main, so it should be valid to declare it.
: As with any function, declaration and definition must be compatible.

Oh, were you talking about C above ?  I'm talking about C++.

: I didn't see any use for declaring main in C++ until someone (sorry,
: I forget who) suggested you might want to make main a friend of some
: class. I see no reason to prohibit that.

I saw that too.  A pity.





Author: JdeBP@jba.co.uk (Jonathan de Boyne Pollard)
Date: 1995/06/08
Raw View
James Kanze US/ESC 60/3/141 #40763 (kanze@lts.sel.alcatel.de) wrote:
: In article <3r5j8f$ffv@silver.jba.co.uk> JdeBP@jba.co.uk (Jonathan de
: Boyne Pollard) writes:
: |> I'm not sure what you mean by "main-function" here (that's certainly not
: |> something that any C++ compiler that I can lay my hands on will accept as a
: |> legal definition for the distinguished function `main'), and I suspect
: |> a language barrier.

: I mean a special type, used internally by the compiler.

But this is irrelevant to the issue at hand, since we aren't discussing the
internal mechanics of the compiler, but how the draft specifies the
acceptable function types for `main' (which it doesn't do at all well).

: In C++, all of the compilers I know of recognize the function main,
: and treat it as a special case.  This could (and maybe does) include
: using a special, compiler internal type, for the function.

Even so, this is still all irrelevant.  Implementations can do whatever
magic they want to recognise the distinguished function main.  The point at
hand is that the draft is self-contradictory when it comes to the function
type of `main', by saying that it is *one* type and then proceeding to give
*two* types.

: |> ( Implementations that allow `int main(int, char **, char **)' and
: |> `void main()' spring to mind. )

: And note that we have something very special here.  The type of main
: must be such that both forms (plus any additional forms the compiler
: accepts) match the function.

No no no no no.  You simply aren't getting it at all.  I'll try again.

The problem is that the *intention* of the draft is that the implementation
defines a set of function types (in the accepted sense of the phrase, and
not anything to do with all of these side issues about internal compiler
magic that you keep trying to side track us on to) that are acceptable
for the definition of `main', and that this set includes at minimum the two
function types `int main()' and `int main(int, char **)'.

However, as currently worded the draft implies something different.
Instead of implying an implementation-defined set of types, from which the
programmer may choose one for the definition of main (as a result of the
prohibition on overloading `main' and the One Definition Rule), what the
draft actually says is that the distinguished function main has *one* type.

As I've said twice already, even if it were intended that `main' have one
type (which it obviously is not), that would be straightway contradicted by
the draft then proceeeding to list *two* possible function types for `main'
that all implementations *must* accept for its definition.

( Note the word "accept" there.  It's important, and is one of the words
that you keep missing in this discussion. )

: There is no way to write this in C++.  The compiler has to use some
: sort of internal magic.  (A special internal type, or something else.)

You're off in a land of your own here.  This argument falls over on its face
when you consider that if it is impossible to write, in C++, a definition
of `main' with a function type acceptable to the implementation, then it is
impossible to write C++ programs with that implementation and it is
to all practical puroposes useless.  No such C++ implementations exist.

: Which means that internally, the compiler must recognize main as a
: special case in one way or another.

I'll say it a fourth time ...

It will need to (I hesitate from saying "must", since it is quite possible
to construct an implementation where `main' is nothing more than a normal
C++ function, overloading and all, and all of the startup magic is
contained elsewhere) recognise a definition of `main' as a special case.

But that doesn't alter the fact that the draft fails to clearly express
the fact that there is expected to be a *set* of (two or more) function types
which the implementation will accept for the definition of `main'.

: Well, the current draft is considerably clearer than your rewording.
: It corresponds to the reality: `main' has *one*
: (implementation-defined) type, regardless of how it is defined.

Wrong.  The function types of `int main()' and `int main(int, char **)' are
clearly different (read [dcl.fct]), and clearly constitute two distinct types.

For the fifth time, the function type of `main' is chosen from a *set* of
types that the implementation defines, and which the draft (should, but
doesn't -- because it is unclear) mandate must contain at the least the two
types specified.

: Your wording is defective in two regards:
:
: 1. It says that the implementation must include definitions for main.
: In fact, the *implementation* is forbidden from defining main.
:
: 2. It suggests that there are a set of definitions, i.e.: more than
: one.  In fact, `main' must have one and only one definition.

Again wrong.  Here is the relevant part of my suggestion :

--------------------------------------------------------------------------
2  This function is not predefined by the implementation.  The set of
   definitions for main that are acceptable (and thus by implication the
   type of main) is implementation defined, and main cannot be [...]
--------------------------------------------------------------------------

It in fact says that `main' MAY NOT be defined by the implementation (first
sentence) and proceeds (second sentence) to say that there is a set of
definitions for main that are ACCEPTABLE to the implementation (i.e. that
the programmer can use and that the implementation will like).

Nowhere in the above does it even *imply* that the programmer may use more
than one such definition in any single program.  Nowhere does it say "the
distinguished function main is exempt from the One Definition Rule".

I have no idea how this can be made any clearer, and it baffles me as to
how you are managing so badly to misread what I wrote.





Author: chris@alofi.etca.fr (Christian Millour)
Date: 1995/06/09
Raw View
In article <3r7lli$4no@silver.jba.co.uk>, JdeBP@jba.co.uk (Jonathan de Boyne Pollard) writes:
|> Steve Clamage (clamage@Eng.Sun.COM) wrote:
|>
|> : I didn't see any use for declaring main in C++ until someone (sorry,
|> : I forget who) suggested you might want to make main a friend of some
|> : class. I see no reason to prohibit that.
|>
|> I saw that too.  A pity.

For the record, I merely answered Steve's interrogation (why would you
want to declare main ?) by providing an example out of published code.
I'm certainly not endorsing the quoted practice. IMHO the existence of
such code demands that the issue of main's declarability (including as
a friend) be explicitely addressed in the standard. I find your rewording

3  ... The function main shall not be declared except at its definition ...

reasonable but AFAIK some developpers might have different needs (imbedded
apps maybe ?).

So, what's next ? Should I make contact with my national body, sending
a copy of your suggestion, or should your own submission be enough ?

--chris@etca.fr





Author: kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763)
Date: 1995/06/09
Raw View
In article <3r7818$b5q@engnews2.Eng.Sun.COM> clamage@Eng.Sun.COM
(Steve Clamage) writes:

|> In article 95Jun8144749@slsvhdt.lts.sel.alcatel.de, kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763) writes:
|> >
|> >I mean a special type, used internally by the compiler.  In C, for
|> >example, it is illegal to declare main, because there *is* no way in
|> >the language to declare a function which can take either no
|> >parameters, or two parameters.  Yet C compilers manage to cope.

|> In C it is explicitly permitted to call main. I know of no rule against
|> declaring main. The C standard also mentions that implementations may
|> permit more than just the two mandated forms of main. A user declaration
|> of main would have to match the definition used in a particular program,
|> but you can have only one external function called "main" in a C (or
|> C++) program. I don't see any problem here.

I seem to have a vague memory about declarations of main being
forbidden in the C standard, but I could easily be wrong.  My C
standard is not nearby at the moment to verify.

Main does need some special handling in certain implementations of C.
For example, I know of at least one C compiler for Intel processors
which uses different calling conventions for functions with variadic
args, and those without.  In functions without variadic args, it is
the called function which cleans up the stack, and not the caller.
This supposes that the called function know how many arg's were
actually passed.

The problem is that the system always calls main with two arguments,
regardless of how the programmer defines main.  In the implementation
in question, this is not a great problem.  If the programmer defines
main without parameters, the stack will not be correctly cleaned up.
But in fact, the implementation is tolerant of this, and it does not
cause any real problems.  One could imagine systems where this
tolerance didn't exist, for example, and the compiler would have to
treat main specially, in order that the start-up procedure could
safely call it.

|> The compiler (C or C++) has to figure out which use of the spelling "main"
|> is the program entry point. That isn't hard. If an entity called "main" has
|> external linkage and is a function (and in C++ is not a member of any class),
|> that's it. ("In the end, there can be only one.") The compiler could then
|> elect to allow only certain function types, and complain about, for example,
|>  double main(FILE*) { ... }
|> Or it might choose to allow anything the programmer wrote.

|> Perhaps you mean you can't write a declaration of main which will
|> survive incorporation in every program. That is true, since the
|> main function in another program might have a different type.

|> I don't see a need to prohibit declaring main.

I agree.  Since whatever logic the compiler uses to recognize the
definition as special could be applied, if necessary to handle the
declaration specially, too.

I simply thought that this was the status quo.  (I've not been at my
home site much in the last two weeks, which means that I don't have
access to my copy of the standard.)
--
James Kanze         Tel.: (+33) 88 14 49 00        email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils en informatique industrielle --
                              -- Beratung in industrieller Datenverarbeitung







Author: kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763)
Date: 1995/06/07
Raw View
In article <3r2a91$m5g@silver.jba.co.uk> JdeBP@jba.co.uk (Jonathan de
Boyne Pollard) writes:

|> A third quibble with [basic.start.main] :

|> The present draft says of the distinguished function `main'

|>  "its type is implementation defined".

|> All well and good, until we look up [dcl.fct] to see what "type" of a
|> function is, and find that it includes the return type as well as the
|> parameter list (I quote : "... and returning T").

|> [ Before anyone says anything, please don't confuse the issue with function
|> overloading and try to assert that you only distinguish the "type" of a
|> function according to the overloading rules.  "Function type" distinguishes
|> among more declarations that do the overloading rules. ]

|> So there's one inconsistency already, since in paragraph 2 the draft says
|> "and its type is ...", implying that `main' has only *one* type, and then
|> immediately proceeds to give *two* possible types for `main' that all
|> implementations must recognise.

|> It is surely better to say that the implementation recognises a set of
|> types for `main', at most one of which may be defined in any one program,
|> which set must include at minimum the types `int main()' and `int main(int,
|> char **)', and which set the implementation is free to extend.

Except that I would expect that most implementations simply have a
special type, main-function, which turns on all of the compiler magic.

Note that it is illegal (I think) to declare main with `extern "C"'
linkage.  Yet the compilers I'm familiar with generally generate main
with C linkage.
--
James Kanze         Tel.: (+33) 88 14 49 00        email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils en informatique industrielle --
                              -- Beratung in industrieller Datenverarbeitung







Author: JdeBP@jba.co.uk (Jonathan de Boyne Pollard)
Date: 1995/06/06
Raw View
A third quibble with [basic.start.main] :

The present draft says of the distinguished function `main'

 "its type is implementation defined".

All well and good, until we look up [dcl.fct] to see what "type" of a
function is, and find that it includes the return type as well as the
parameter list (I quote : "... and returning T").

[ Before anyone says anything, please don't confuse the issue with function
overloading and try to assert that you only distinguish the "type" of a
function according to the overloading rules.  "Function type" distinguishes
among more declarations that do the overloading rules. ]

So there's one inconsistency already, since in paragraph 2 the draft says
"and its type is ...", implying that `main' has only *one* type, and then
immediately proceeds to give *two* possible types for `main' that all
implementations must recognise.

It is surely better to say that the implementation recognises a set of
types for `main', at most one of which may be defined in any one program,
which set must include at minimum the types `int main()' and `int main(int,
char **)', and which set the implementation is free to extend.