6

Can the main function be declared like so :

template<typename T1, typename T2>
int main(T1 argc, T2 *argv[])
{
}

For an instantiation T1 = int and T2 = char we end up to a common signature.

The restrictions for main mention nothing about templates :

  • No other function in the program can be called main

  • main cannot be defined as inline or static.

  • C++main cannot be called from within a program.

  • C++ The address of main cannot be taken.

  • C++ The main function cannot be overloaded.

Apparently there are no applications of such a syntax, but

  • Is there a compiler that implements it ?
  • Are there any logical barriers in implementing something like that ?

EDIT

I was a bit vague in my first attempt to asking the above. There were (rightfully) some negative remarks on the question, so I should lay down some reasoning on asking for feedback on this topic :

  • C++ is an evolving language, maybe this was to be implemented and someone is aware of it

  • Someone could inform me on why main has the limitations that it has

  • A language lawyer could find a loophole in the Standard to allow for such a declaration (well the opposite has happened)

  • The evolution of the modules system drives the language to a logic of component separation (in terms of compilation units for now). Maybe this will affect the way we spawn compiled units, maybe multiple main functions are to be defined across submodules in which case a more flexible main would be needed.

An example use case of templatizing main

If the Standard was to allow for something like that (in the future) we could write

template<typename... Args>
int main(Args&& ...vs)
{
}

there you go, safe command line arguments parsing (have I invented the wheel or what?)

Nikos Athanasiou
  • 29,616
  • 15
  • 87
  • 153
  • 4
    Can you think of a single valid use case for this ? How would you even instantiate it ? – Paul R May 08 '14 at 22:33
  • 1
    @PaulR Can you ask me something I'm not already mentioning in the question? – Nikos Athanasiou May 08 '14 at 22:35
  • 3
    @PaulR, the use case is asking obscure questions on SO ;) – M.M May 08 '14 at 22:39
  • 3
    @Nikos how are you planning to instantiate this template? – M.M May 08 '14 at 22:41
  • This question doesn't seem to fall under the requirement for "**practical**, answerable problems that are unique to software development" in the [FAQ](http://stackoverflow.com/help/on-topic). ;-) – Paul R May 08 '14 at 22:41
  • @PaulR Yet 3 answers and 8 comments in under 15 minutes. I guess people are interested in learning the [`why`](http://stackoverflow.com/q/21712823/2567683) as well ;) – Nikos Athanasiou May 08 '14 at 22:48
  • @PaulR OK I thought of one use – Nikos Athanasiou May 08 '14 at 23:41
  • The call of `main` resolves at runtime afaik, so I guess that isn't possible to templatize `main` because `template`s are a compile-time construct. However, about your example use case of templatizing `main` I was wondering something quite similar asking [Why initializer list cannot be `main` parameter](http://stackoverflow.com/questions/19099615/why-initializer-list-cannot-be-mains-parameter-how-to-propose-it) – PaperBirdMaster May 09 '14 at 07:26
  • @NikosAthanasiou: Noone gave you a loophole allowing an implementation to accept such? I think I gave the exact standard quotes allowing it, irrespective of it making sense and/or being a complicated process with little reward. – Deduplicator May 09 '14 at 10:20

3 Answers3

17

This:

template<typename T1, typename T2>
int main(T1 argc, T2 *argv[])
{
}

is really a function template. The Standard, as per §3.6.1/1, requires main to be a function:

A program shall contain a global function called main, which is the designated start of the program.

Just like classes and class templates are not the same thing, function and function templates are two different things. More specifically, as per §14.1:

A template defines a family of classes or functions or an alias for a family of types.

Therefore a function template can "generate" a potentially infinite set of functions.

† is arguable

Shoe
  • 74,840
  • 36
  • 166
  • 272
  • 2
    +1 This explains why the Standard does not even have to mention templates – Nikos Athanasiou May 08 '14 at 22:41
  • 3
    There remains the question of whether `main` can be a function instantiated from a template. It's then a "function" (as many folks who have forgotten to `inline` a function in a header have discovered), and called `main`. Hm. – Cheers and hth. - Alf May 08 '14 at 22:44
  • Only applies to hosted environments. You don't get the banana. Also, leaves out the issue of extensions. – Deduplicator May 08 '14 at 22:44
  • @Cheersandhth.-Alf, You can't instantiate it without using it, and that is not allowed, as per §3.6.1/3 ("The function main shall not be used within a program."). – Shoe May 08 '14 at 22:46
  • @Jefffrey Yes, you can: http://stackoverflow.com/questions/4933056/how-do-i-explicitly-instantiate-a-template-function – SomeWittyUsername May 08 '14 at 22:47
  • Anyway, neither Visual C++ nor g++ accepts it. And g++ even has a special diagnostic for it: "cannot declare '::main' to be a template". But I'm not sure that this is in line with a pedantic literal interpretation of the Holy Standard. – Cheers and hth. - Alf May 08 '14 at 22:48
  • @icepack, it would still be a *function template specialization*. And `main` would still remain a *function template*. – Shoe May 08 '14 at 22:53
  • 1
    @Jefffrey It's not a specialization but rather an instantiation (the linked question specifically emphasizes this point). Relation between function and it's template is similar to relation between class and its template. The function can be instantiated even without actually using it (i.e. calling) - http://ideone.com/RcPHn2 – SomeWittyUsername May 08 '14 at 22:58
  • @icepack §14.8/1 says "A function instantiated from a function template is called a function template specialization;" -- And it still doesn't change the fact that `main` would be a function template and not a function. – Shoe May 08 '14 at 23:37
  • @icepack "instantiation" is the process of generating a "specialization". – R. Martinho Fernandes May 08 '14 at 23:53
  • @Jefffrey, R.MartinhoFernandes That's true although a standard is a bit vague about it. You can instantiate a template function without providing a specialized definition (which is normally what specialization is about) - it can be seen as a private case of specialization. But that's not the point here - you can instantiate the function in ways that do not necessary include its usage. Thus after the specialization/instantiation there will be a main function compliant to the standard. – SomeWittyUsername May 09 '14 at 00:04
  • @icepack the name `main` would still refer to a function template, and would, therefore, not be a function (eg. not allowed). Can you make an example in which `main` does not refer to a function template, to prove your assertions? – Shoe May 09 '14 at 00:06
  • 2
    @Jefffrey The standard talks about existence of function named "main" (and it will be created upon template instantiation), not about restrictions on naming other symbols for the parser, whether it's template name or something else (maybe there are such restrictions, but they're surely not present in the excerpts that you had quoted). – SomeWittyUsername May 09 '14 at 00:17
  • 2
    @icepack, I'll take that as a no. Again, and for the last time: the Standard says `main` has to be a function. If you declare `main` as a template function and instantiate it as, for example, `int main(...);` like you did, that doesn't change the fact that `main` is not a function but a function template. `int main(...)` would be a valid function instantiation, but `main` and `main` are two different names that refers to two different things, and the latter has to be a function. – Shoe May 09 '14 at 01:43
  • 1
    @Jefffrey I don't see a basis for *such* interpretation. As far as the user (programmer) is concerned, once the instantiation has occurred, there is a function called main. Template parameters belong to entirely different domain, they are irrelevant and meaningless at this stage, they are not part of the function properties. Also, symbolic name in the binary is not part of the standard and whether or not it's different between a regular function and function instantiated via template is irrelevant. – SomeWittyUsername May 09 '14 at 05:29
  • @icepack This conversation is exactly the kind of input I was hoping for. Seeing the debate was not only in my imagination is really rewarding. I believe further analyzing language trivias is pointless, so the real question is would there be any basis for such a proposal (a new language feature), or if I do make one would anyone like to co-author? – Nikos Athanasiou May 09 '14 at 06:25
  • @NikosAthanasiou Seems like PaperBirdMaster pointed out a real technical issue with templatizing main - call resolution at runtime vs. template instantiation during compilation. – SomeWittyUsername May 09 '14 at 08:27
  • 8
    @icepack: What some user thinks is irrelevant. The Standard makes it pretty clear how name lookup works (i.e. what a specific name means in any given context). `::main` must name a function, not a function template. In the example given, `::main` names a template. A template instantiation could be a function, but does not have a name. – MSalters May 09 '14 at 08:28
  • @MSalters That's exactly what I'm asking - does the standard define *how name lookup works* at compilation or it merely requires a function named main to exist? – SomeWittyUsername May 09 '14 at 08:33
  • 1
    @icepack Why don't you check that yourself and go back to us when you're done with it? – Bartek Banachewicz May 09 '14 at 09:37
  • 1
    @Jefffrey: Nice how you always repeat what the standard prescribes for a hosted environment without extensions. Does not hinder aanyone to alow such startup for his freestanding environment or as an extension, even if it's a lot of extra work and special-casing main, which is a special case for hosted environments anyway. – Deduplicator May 09 '14 at 09:44
  • @Deduplicator, I don't have the slightest clue about what you are talking about. We are discussing over what the standard says here. Never mentioned hosted environments nor extensions. No one has, except you. – Shoe May 09 '14 at 09:50
  • 1
    @icepack there's no "at compilation". The standard defines *how name lookup works*. Period. – R. Martinho Fernandes May 09 '14 at 09:50
  • Yes, because you blithely ignore the fact that **your standard quotes do not concern freestanding environments nor extensions**, leaving both completely unexplored. – Deduplicator May 09 '14 at 10:23
  • 2
    @Deduplicator: The question is tagged C++, which implies standard C++. We have other tags for extensions, such as msvc++. – MSalters May 09 '14 at 10:48
  • @MSalters: Even if your implementation has extensions, it is still C++. The OP did not ask about a specific implementation, so using the main C++ tag only is right, even if the answer has to take into account the possibility of extensions. By your logic btw, a huge part of the questions labeled C++ is grievously mislabeled. Want to bring it up on meta for a cleanup effort? – Deduplicator May 09 '14 at 10:54
  • @Deduplicator, "C++" refers to the standardized ISO C++, which does not mention implementations and/or extensions. For more informations see: [tag:C++]. – Shoe May 09 '14 at 11:33
  • @Jeffrey: Neither the tag wiki nor the questions filed under the tag support your narrow interpretation that only questions using standard C++ without any extensions may be tagged C++. Please open a meta-discussion if you want to change the usage of the tag. – Deduplicator May 09 '14 at 12:00
  • 1
    @Deduplicator, Oh, I see. Could you please tell me where, in the wiki, it says questions tagged with C++ should include extensions? (Hint: nowhere). If you have something more to add on extensions or anything, please feel free to provide your own answer. Good Bye. – Shoe May 09 '14 at 12:03
  • It does not exclude them, that's enough (If it were not, the majority of questions tagged C++ are mis-tagged). Where does either this question or the tag wiki ban extensions or freestanding implementations, or where is such a ban supported by what gets tagged C++? Please point it out. – Deduplicator May 09 '14 at 12:07
  • If you add the disclaimer that your answer only applies for hosted implementations without extensions, your answer will be correct. This way it is simply wrong. – Deduplicator May 09 '14 at 12:11
  • @Deduplicator I'm curious, how is my answer wrong for "freestanding implementations" including "extensions"? – Shoe May 09 '14 at 12:19
  • 4
    Don't you know you can write non-standard C++ and it might not even look like C++ how dare you not include that very relevant tidbit that everyone will need to keep in mind in your answer??? – Cat Plus Plus May 09 '14 at 12:22
  • @Jefffrey: Is said wrong for either, not for both together. Freestanding implementations can omit that whole chapter. Second sentence: "It is implementation-defined whether a program in a freestanding environment is required to define a main function.". It is wrong with extensions, because an extension is allowed to do anything which *does not alter the behavior of a strictly-conforming program*. Especially, they may assign any useful semantics they want to an illegal construct *after issuing a diagnostic of it being illegal*. The chapter *implementation compliance* explicitly lists that. – Deduplicator May 09 '14 at 12:25
  • @Deduplicator, see and cast an upvote [here](http://stackoverflow.com/a/23564719/493122). – Shoe May 09 '14 at 12:31
16

It depends. In my own super-secret and private freestanding implementation you can make the main function be a template if all the following conditions apply.

  • The function is named mаin (note that the second letter is a Cyrillic letter, not a Latin letter).
  • There are either 2, 17, or 23 non-pack template arguments, or a lone variadic pack.
  • If the template arguments consist of a variadic pack, it is introduced with class, not typename, there is no space between class and dot-dot-dot, and there is a single space between dot-dot-dot and the pack name.
  • It's a full moon and you're in the Northern hemisphere, or you're in the Southern hemisphere and Mars is above the horizon. (Compilation without GPS or ASCOM is not supported.)

All of this information is obviously completely useless in face of the question presented, but who cares? At least it mentions freestanding implementations and language extensions.

R. Martinho Fernandes
  • 228,013
  • 71
  • 433
  • 510
  • Also it only runs on PCP. – Cat Plus Plus May 09 '14 at 12:35
  • 4
    +1 For the humor, you're so funny dude hahah. Does this implementation issue a sarcastic handclap when compilation fails ? If not I could give you one. I should also select the answer so everyone can see how funny you are. – Nikos Athanasiou May 09 '14 at 12:44
  • 3
    If you're under Southern skies but cannot see Mars, you could simple reverse the order of the arguments, (not tried, but should work). – Martin James May 09 '14 at 12:53
2

In principle, taking full advantage of the latitude the standard leaves to implementations, yours may decide to allow that one.

Still, I don't know any implementation which does when using main as the starting point, nor a reason to do so.

This allows it as an extenson, useable after issuing at least one diagnostic:

1.4 Implementation compliance §8

A conforming implementation may have extensions (including additional library functions), provided they do not alter the behavior of any well-formed program. Implementations are required to diagnose programs that use such extensions that are ill-formed according to this International Standard. Having done so, however, they can compile and execute such programs.

This one allows it for freestanding environments even without diagnostics:

3.6.1 Main function [basic.start.main]

1 A program shall contain a global function called main, which is the designated start of the program. It is implementation-defined whether a program in a freestanding environment is required to define a main function. [ Note: In a freestanding environment, start-up and termination is implementation-defined; startup contains the execution of constructors for objects of namespace scope with static storage duration; termination contains the execution of destructors for objects with static storage duration. —end note ]

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
  • "Still, I don't know any implementation which does, nor a reason to do so" - well, if the environment doesn't prohibit it, it's doable. I've just checked this for a Windows device driver (freestanding environment) - compiles like a charm, main is no different from any other function there. – SomeWittyUsername May 09 '14 at 09:56
  • @icepack: Thanks. There I actually restricted my view to those using `main` as their starting point, which was not required. – Deduplicator May 09 '14 at 10:34