2

I know you might think this question already been answered but it is not, or at least it was not very clear to me.

int WINAPI WinMain (){}

This is a pseudo form of the famous winmain function.

My question is about the calling convention WINAPI, in particular its placement between the "return type" and the "function name". Is this Standard C? Because I referenced the Brian W. Kernighan and Dennis M. Ritchie book and I didn't see this form.

I also have searched for its meaning and they said it's a macro to place _stdcall instead. So please don't tell me the question is duplicated.

And here is one of the questions that might be very close to mine What does "WINAPI" in main function mean?

I want a clear answer for this WINAPI: Is it standard C? So I can place a calling convention after the return type in any function declaration and I then give it to any C compiler in the world? Or is it something will work only on Microsoft compilers? And if so, can anyone impose their rules on the C syntax?

I'm sorry I know my question might be trivial for many of you, but I searched everywhere about the functions declaration syntax and all sources denied this calling convention place.

Community
  • 1
  • 1
the accountant
  • 506
  • 6
  • 14
  • From the question you linked: WINAPI is a macro that evaluates to __stdcall, a **Microsoft-specific** keyword – Denilson Amorim May 14 '15 at 23:49
  • 1
    `WINAPI` is indeed a synonym for `__stdcall`, and everything with `_` in the beginning is compiler-specific. Stdcall is a known calling convention outside of MS too, but how to set set it for functions is a different story. Btw, your WinMain is missing paramters. – deviantfan May 14 '15 at 23:51
  • @thelink2012, thanks , but is it place between the return type and the function name also a Microsoft specific? or it just the keyword? – the accountant May 14 '15 at 23:51
  • 1
    @big.heart Yep, on GCC _(not MinGW, MinGW accepts Microsoft-specific extensions)_ for instance it uses `__attribute__((stdcall))` at the beggining / end of the full function signature (except there's no `stdcall` on e.g. linux, but for instance `fastcall` would work). – Denilson Amorim May 14 '15 at 23:54
  • @thelink2012 . So any compiler maker can actually make his own C syntax? as you say GCC can but the calling convention keyword at the begin or the end of the signature ? – the accountant May 15 '15 at 00:00
  • 1
    @big.heart While a C compiler should "at least" support what´s written in the standard, everyone is allowed to make additional things, yes. – deviantfan May 15 '15 at 00:01
  • 1
    When you write the compiler, you can set the rules. If people use your compiler enough, it becomes the de facto standard -- at least for the systems where your compiler is used. Microsoft has persuaded enough people that it is a good idea to use their compiler that `WINAPI` is a standard on their systems. It isn't a de jure standard; the C standard from ISO says nothing about it. When you write the standard, you can do what you like; the placement of `WINAPI` becomes a matter of where the people designing the compiler decided it should go. – Jonathan Leffler May 15 '15 at 00:05
  • @deviantfan . thank you very much, now I get it. one more thing to go , is these "additional things" you just said is what Greg Hewgill call them in his answer a "Microsoft EXTENSION" ? or it is something else? – the accountant May 15 '15 at 00:06
  • 1
    It is a Microsoft extension. It was devised by Microsoft for their own reasons. No-one else invented it. It isn't part of the standard, so it is an extension to the standard. That makes it a Microsoft extension by any reasonable definition. – Jonathan Leffler May 15 '15 at 00:07
  • 1
    @big.heart Yes, he means the same stuff. A extension [of the language], made by Microsoft for their compiler. – deviantfan May 15 '15 at 00:07
  • @JonathanLeffler thank you very much , crystal clear :) – the accountant May 15 '15 at 00:51

4 Answers4

5

The essential answer: No. A function declaration, as defined by the C language standard, has no elements between the return type and the function name. So int __bootycall myFunc(int qux) is not standard C (or C++), even though C implementations are allowed to reserve __customIdentifiers for their own exclusive use.

However.

The need for calling-convention specifiers (e.g. __cdecl) is clear; a lot of (especially early non-UNIX [especially MS-DOS]) platforms had more than one calling convention to choose from, and specifying the calling convention of a function was as important as, if not more important than, the parameter list of that function. Hence the need to slot a little something extra in there.

At that time (even before C89), there was no provision made for architecture-specific function attributes (presumably because C, designed for the sole purpose of implementing UNIX utilities, didn't need any). This would later be remedied in C99, and if C99 had existed at that point, it's likely that __cdecl et al. would have been function attributes, not random identifiers shoved in there. But as it was, when the need arose to specify non-default calling conventions, there were four reasonable places to put it: Before the return type, between the return type and the function name, between the function name and the opening parenthesis of the argument list, and after the argument list.

I'm speculating here, but it seems like the second option would have made the most sense. This was pre-C++, remember; there was no post-arglist-const, and the only thing that could show up before the return type was static, which specified linkage rather than anything about the function per se. That left before or after the function name, and separating the function name from its argument list would have reduced readability. That left the slightly unusual position between the return type and the function name as the best of a bad bunch.

The rest is history. Later compilers took advantage of the nascent __attribute__ syntax to put the calling convention keyword in a more appropriate place, but DOS-based compilers (of which Microsoft C was one of the first) shoved it after the return type.

Sneftel
  • 40,271
  • 12
  • 71
  • 104
  • `after the return type` => `before the function name` as `int static __cdecl a(){}` also works. – cremno May 15 '15 at 01:26
2

The answer to your clear question:

WINAPI, Is it a standard C?

is No. __stdcall is a Microsoft extension.

Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
  • `__stdcall` the keyword is a Microsoft specific , but what about it's PLACE between the return type and the function name, is it something special to Microsoft also , thanks for the answer. – the accountant May 14 '15 at 23:55
  • @big.heart This question makes no sense. It isn´t allowed anywhere, of course. `int i = __stcall + __stcall;` and things like that are nonsense. – deviantfan May 14 '15 at 23:59
  • 1
    @big.heart: There is no such thing as a "calling convention" in the C standard. So yes, the placement of `__stdcall` between the return type and function name is also specific to Microsoft's compiler. However, other compilers may have their own extensions (which may or may not be related to calling convention) that may occupy the same place between return type and name. – Greg Hewgill May 15 '15 at 00:05
  • @Greg Hewgill ahhh thanks, now I can go die in peace – the accountant May 15 '15 at 00:09
2

Both the __stdcall and the position of the keyword are Microsoft specific. Any compiler vendor is able to add non-standard syntax to their implementation.

At the very top of this MSDN article:

Microsoft Specific

It also mentions the WINAPI macro at the end of the page:

In the following example, use of __stdcall results in all WINAPI function types being handled as a standard call: [...]`

This form works on both Microsoft C++ Compiler and the MinGW toolchain, which implements GCC for Windows.

But in general GCC uses this other form using it's attributes:

int WinMain() __attribute__((stdcall)) // or WINAPI if using the macro
{}

It's possible however that in the future we have those in a more standard syntax (the stdcall part still being platform specific) by using the recent C++11 generalized attributes such as.

[[ms::stdcall]]
int WinMain() {}

In fact both GCC and Clang already supports the standard generalized attributes as an alternative to the compiler specific attribute syntax.

Denilson Amorim
  • 9,642
  • 6
  • 27
  • 31
1

WINAPI is a macro defined in windows.h, which expands to __stdcall. Both windows.h and __stdcall are Windows-specific -- no industry-wide standard defines any aspect of their meaning.

The C and C++ standards do define keywords that have related effects on a function definition: inline, _Noreturn (C2011), and static. All of these keywords are normally placed before the return type, but if I'm reading C2011 correctly, this is not actually required by the syntax: you could perfectly well write

int static foo(void) { return 42; }

These keywords are called function specifiers and storage class specifiers. Do not confuse them with type specifiers and type qualifiers, which can also appear in this position, but modify the return type when they do.

zwol
  • 135,547
  • 38
  • 252
  • 361