What does "cdecl" stand for?
Asked Answered
H

8

42

Yes, I know that "cdecl" is the name of a prominent calling convention, so please don't explain calling conventions to me. What I'm asking is what the abbreviation (?) "cdecl" actually stands for. I think it's a poor naming choice, because at first sight it reminds one of "C declarator" (a rather unique syntactic aspect of C). In fact, there is a program called cdecl whose sole purpose is to decipher C declarators. But the C declarator syntax has absolutely nothing to do with calling conventions as far as I can tell.

Simplified version: "stdcall" stands for "standard calling convention". What does "cdecl" stand for?

Howie answered 13/2, 2011 at 21:0 Comment(8)
I always presumed that it was "C-declared" - most C compilers use the convention by default, so that's what you would specify as the calling convention if you wanted to call out to compiled C code.Ruffner
"the C declarator syntax has absolutely nothing to do with calling conventions" - surely it has something to do with it, in that the calling convention is for functions declared as C functions. As opposed to Fortran functions, etc. Granted, it has nothing in particular to do with C declarations other than functions.Yeo
This is 2011. Surely the fact that ordinary application programmers (not systems programmers) are still asking questions about ridiculous implementation details of Windows says a lot about the quality of Windows development resources and Windows as a platform...Laplace
@R..: yes, it pretty much disproves the dot-com prediction of java making Windows irrelevant.Pyrimidine
@R.. What "ridiculous implementation details" are you talking about? I was just asking where the name came from. Did you actually bother to read my question?Howie
@R.. Windows development resources are fantastic. I suspect you are spouting off from a position of some ignorance on this particular topic.Tushy
Leave the acronym to the lawyers. The greater question is: is it only for functions? Or can I apply it to an int or array declaration? And how does it distinguish with extern "C" Aerugo
Yes, this is why I "love" c / c++ that muchHeflin
C
6

The term CDECL originates from Microsoft's BASIC and their Mixed Language Programming ecosystem. The ecosystem permitted any of the Microsoft's four major languages (BASIC, FORTRAN, Pascal and C) to make calls to any other. Each language had a slightly different calling convention, and each had a way to declare an external function or procedure to be using a specific convention.

In BASIC, the DECLARE statement had to be used before you could call an external function with the CALL statement. To denote an external FORTRAN or Pascal procedure or function, you would write one of

DECLARE SUB Foo ()
DECLARE FUNCTION Foo ()

C calling conventions differed from the other languages in part because the arguments were pushed on the stack in reverse order. You would inform BASIC of this by adding the CDECL modifier:

DECLARE SUB Foo CDECL ()
DECLARE FUNCTION Foo CDECL ()

By contrast, when writing in FORTRAN or Pascal, the modifier is [C]. This is an indication CDECL was specific to BASIC's DECLARE statement and not a previously established term. At the time, there was no specific term for "C calling conventions". Only with the advent of new calling conventions in WIN32 (stdcall, fastcall, etc) did "cdecl" get co-opted and become the de-facto name to refer to the legacy conventions in the absence of another term.

In summary, CDECL means "C declaration". It had its origins in BASIC compilers, not C compilers, and it was an arbitrarily-chosen BASIC keyword, and somewhat redundant because plain "C" could not be a keyword.

Details about CDECL can be found in this 1987 document:

https://archive.org/details/Microsoft_Macro_Assembler_5.1_Mixed_Language_Programming_Guide/page/n1/mode/2up?q=cdecl

Cannot answered 4/11, 2021 at 0:2 Comment(0)
M
34

It comes from C function that was declared (in contrast to a C function that was not declared which was common in K&R C).

At the time it was coexisting with pascal calling convention (wher the callee cleared the stack), so it kind of made sense to call it after the programming language.

Everything you might ever want to know about calling conventions.

Margertmargery answered 13/2, 2011 at 21:13 Comment(10)
I'm sure the linked PDF is an interesting read, but it doesn't answer my question.Howie
@FredOverflow doesn't the answer answer your question? "It comes from a C function that was declared". I.e int main() { char c = 0; f(c); } passes an int, and void f(c) char c; { } in the binary code, even though the parameter type is char, needs to read the parameter data as an int. If you had a void f(char c) in scope and a void f(char c) { }, the data would be passed and read as a charHexa
@FredOverflow: the link was only added as an extra info source.Margertmargery
@litb: yeah exactly what I'm meaning, thanks for the clarifying exampleMargertmargery
@JohannesSchaub-litb: This answer would only make sense if C functions which are not declared do not use a cdecl calling convention, so you had something to contrast with – but that is wrong.Transpontine
@Fred I'm not arguing in favor or against this answer. I don't know whether implicitly declared functions use that calling convention or not on whatever platform.Hexa
@JohannesSchaub-litb: I'm just going by your previous comment. "Doesn't the answer answer your question?" => No. The difference between parameter types (your example uses int and char) matters to all calling conventions.Transpontine
@Fred I just said that this is an answer. I didn't want to say that this is necessarily correct or incorrect or something. "The difference between parameter types (your example uses int and char) matters to all calling conventions.". I'm not sure what you want to say by that.Hexa
Hm how about telling why the -1, having something to share to improve the answer?Margertmargery
Isn't the reference saying that undeclared C-functions and variable argument C-function need this variant (to be able to extract first argument without knowing how many) whereas Pascal knows the number of argument and don't need that and thus had a different calling convention?Fountainhead
T
17

You're reading too much into this. It stands for the calling convention of the implementation for calling C functions in general (but especially important with varargs).

It doesn't have to be an abbreviation for something that combines "C" and "declaration"; names are just names, especially in programming. Mnemonics help, but even though "malloc" means "allocate memory", it has additional meaning that we know and attach to it; "alloca" also "allocates memory", for example.

Or take "struct" which "means" a "structure", but "structure" is so generic by itself that without the meaning we attach subconsciously to "struct" we would be hopelessly lost – as new programmers still learning the terminology are often lost.

Transpontine answered 13/2, 2011 at 22:23 Comment(3)
But only it does mean something ... see my answerMargertmargery
@PeerStritzinger: I didn't say it means nothing, but, uh, thanks for the downvote because you misunderstood.Transpontine
This answer is responding to an etymology question with a definition. Yes, words have meanings beyond their etymology, but they still have etymologies too.Fadiman
P
13

C declaration. A declaration introduced by/for C.

[edit]

I honestly have to admit I don't actually know if that is what is stands for, although it is actually introduced by/for C. But since the caller has to clean up allocated memory (as opposed to most other calling conventions). It could also be a mnemonic for 'Caller Does End CLeaning' which I think is actually a good memory aid. :D

Picasso answered 13/2, 2011 at 21:3 Comment(12)
+38 off the back of that piece of blatant fiction! Nice work if you can get it, but you are the one that has to try to sleep at night!! ;-)Tushy
And that's why I didn't enter my IP address in my profile. ;-)Picasso
You should do the decent thing and give back all that rep!Tushy
Yeah, you're right. And because I couldn't find the real answer, I'd like to add a bounty on this question. How to I do that? And I've given my vote to Peer Stritzinger. He could be making this up as well, but his answer seems more fundamental.Picasso
I think you have to wait for some time (7 days perhaps), and the Q doesn't have an accepted answer. Then you can offer bounty.Tushy
I like the "Caller Does End CLeaning" fiction, but unfortunately, both "Caller" and "Callee" start with the letter 'C', so it doesn't really work as a memory aid :-(Howie
@FredOverflow. Didn't think of that. :-/Picasso
But I'm still googling else I can't sleep tonight;) And every source I find states it means "C declaration", although most of them are argumented just as much a my answer.Picasso
I wonder which answer you want to reward. After all the only answer putting it clear (i.e. cdecl == C declaration) is your own ....Unfrock
I was hoping for a more conclusive answer, since this is declared nonsense :0Picasso
Well the text says " reward an existing answer" Not looking for new answersUnfrock
Yes. I think it's not really possible to change anything after creating the bounty. Anyway, I let it slide, and although I'm surprised at which answer got the (half) bounty by auto-assignment, at least it's probably the best answer anyway :DPicasso
C
6

The term CDECL originates from Microsoft's BASIC and their Mixed Language Programming ecosystem. The ecosystem permitted any of the Microsoft's four major languages (BASIC, FORTRAN, Pascal and C) to make calls to any other. Each language had a slightly different calling convention, and each had a way to declare an external function or procedure to be using a specific convention.

In BASIC, the DECLARE statement had to be used before you could call an external function with the CALL statement. To denote an external FORTRAN or Pascal procedure or function, you would write one of

DECLARE SUB Foo ()
DECLARE FUNCTION Foo ()

C calling conventions differed from the other languages in part because the arguments were pushed on the stack in reverse order. You would inform BASIC of this by adding the CDECL modifier:

DECLARE SUB Foo CDECL ()
DECLARE FUNCTION Foo CDECL ()

By contrast, when writing in FORTRAN or Pascal, the modifier is [C]. This is an indication CDECL was specific to BASIC's DECLARE statement and not a previously established term. At the time, there was no specific term for "C calling conventions". Only with the advent of new calling conventions in WIN32 (stdcall, fastcall, etc) did "cdecl" get co-opted and become the de-facto name to refer to the legacy conventions in the absence of another term.

In summary, CDECL means "C declaration". It had its origins in BASIC compilers, not C compilers, and it was an arbitrarily-chosen BASIC keyword, and somewhat redundant because plain "C" could not be a keyword.

Details about CDECL can be found in this 1987 document:

https://archive.org/details/Microsoft_Macro_Assembler_5.1_Mixed_Language_Programming_Guide/page/n1/mode/2up?q=cdecl

Cannot answered 4/11, 2021 at 0:2 Comment(0)
D
4

The cdecl (C Declaration) calling convention is usually the default calling convention for x86 C compilers

In computer science, a calling convention is an implementation-level (low-level) scheme for how subroutines receive parameters from their caller and how they return a result. Differences in various implementations include where parameters, return values, return addresses and scope links are placed (registers, stack or memory etc.), and how the tasks of preparing for a function call and restoring the environment afterwards are divided between the caller and the callee.

(Source)

Calling conventions may be related to a particular programming language's evaluation strategy, but most often are not considered part of it (or vice versa), as the evaluation strategy is usually defined on a higher abstraction level and seen as a part of the language rather than as a low-level implementation detail of a particular language's compiler.

(Source)

The cdecl (which stands for C declaration) is a calling convention that originates from Microsoft's compiler for the C programming language and is used by many C compilers for the x86 architecture. In cdecl, subroutine arguments are passed on the stack. Integer values and memory addresses are returned in the EAX register, floating point values in the ST0 x87 register. Registers EAX, ECX, and EDX are caller-saved, and the rest are callee-saved. The x87 floating point registers ST0 to ST7 must be empty (popped or freed) when calling a new function, and ST1 to ST7 must be empty on exiting a function. ST0 must also be empty when not used for returning a value.

In the context of the C programming language, function arguments are pushed on the stack in the right-to-left order, i.e. the last argument is pushed first.

Consider the following C source code snippet:

int callee(int, int, int);

int caller(void)
{
    return callee(1, 2, 3) + 5;
}

On x86, it might produce the following assembly code (Intel syntax):

caller:
    ; make new call frame
    ; (some compilers may produce an 'enter' instruction instead)
    push    ebp       ; save old call frame
    mov     ebp, esp  ; initialize new call frame
    ; push call arguments, in reverse
    ; (some compilers may subtract the required space from the stack pointer,
    ; then write each argument directly, see below.
    ; The 'enter' instruction can also do something similar)
    ; sub esp, 12      : 'enter' instruction could do this for us
    ; mov [ebp-4], 3   : or mov [esp+8], 3
    ; mov [ebp-8], 2   : or mov [esp+4], 2
    ; mov [ebp-12], 1  : or mov [esp], 1
    push    3
    push    2
    push    1
    call    callee    ; call subroutine 'callee'
    add     esp, 12   ; remove call arguments from frame
    add     eax, 5    ; modify subroutine result
                      ; (eax is the return value of our callee,
                      ; so we don't have to move it into a local variable)
    ; restore old call frame
    ; (some compilers may produce a 'leave' instruction instead)
    mov     esp, ebp  ; most calling conventions dictate ebp be callee-saved,
                      ; i.e. it's preserved after calling the callee.
                      ; it therefore still points to the start of our stack frame.
                      ; we do need to make sure
                      ; callee doesn't modify (or restores) ebp, though,
                      ; so we need to make sure
                      ; it uses a calling convention which does this
    pop     ebp       ; restore old call frame
    ret               ; return

The caller cleans the stack after the function call returns.

The cdecl calling convention is usually the default calling convention for x86 C compilers, although many compilers provide options to automatically change the calling conventions used. To manually define a function to be cdecl, some support the following syntax:

return_type __cdecl func_name();

Calling convention is the name of the calling convention. __cdecl, __stdcall, __pascal and __fastcall can be specified explicitly in C++ function declarations for compilers that support these conventions. __cdecl is the default for applications and static libraries. __stdcall is the default for system calls (including Windows API calls) and recommended for library DLL's in 32-bit Windows. __thiscall is used by default in Microsoft compilers for member functions in 16 and 32 bit mode. Microsoft, Borland, Watcom and Gnu are brands of compilers. Intel compilers for Windows are compatible with Microsoft. Intel compilers for Linux are compatible with Gnu. Symantec, Digital Mars and Codeplay compilers are compatible with Microsoft. In 64 bit mode, there is one default calling convention for each operating system, while other calling conventions are rare in 64 bit mode.

Other Conventions:

  • __pascal
  • __fortran
  • __thiscall
  • __stdcall
  • __fastcall
  • __msfastcall
  • __regcall
  • __vectorcall

(Source)

Dispense answered 3/11, 2021 at 14:56 Comment(0)
L
1

C has the concept of functions and variables, assembler / machine-code do not. When one wants to pass values to functions, this needs to be done either using cpu registers, or a value in memory at a fixed offset from a register (normally the designated stack pointer). Thus when we jump to a new address at the start of our function, the right values are in the right places so that the function performs correctly. Same applies for return values.

How this works in practice is defined in a document that describes to system's calling conventions. The calling convention is something unique to both the CPU architecture and the operating system.

On x86 Windows there are a number of calling conventions that are used. In the "cdecl" calling convention the caller places functions on the stack for the callee to use. Once the function completes, the caller cleans up its own stack.

Windows APIs use the "stdcall" calling convention which is similar the cdelc except that the callee cleans up the stack. (This means vararg function calls call cannot be used). It has the benefit of saving code space.

Windows also has a "fastcall" calling convention that makes use of registers for parameter passing.

Since windows allows multiple calling conventions, C compiler (cl) extends the C language with __cdecl, __stdcall and __fastcall. This decorates the function declaration and allows the programmer to specify the calling convention used.

Other platforms like ARM, Itanium and others have their own calling conventions.

Lubet answered 28/10, 2021 at 15:15 Comment(0)
P
1

CDECL has no abbreviation, it's just name for calling convention.

If that was not what you were looking for, but actually the history of CDECL then:

It's a Microsoft specific calling convention attribute (at the time of introduction somewhere between 1985 and 1995), that later became the standard.

Too bad page is lost from Internet (wayback also has nothing), but who has old MSDN CD's might find topic "Summary of Declaration" inside "C Language Reference" that clearly states following:

attribute-seq : /* attribute-seq is Microsoft Specific */

attribute attribute-seq opt attribute : one of /* Microsoft Specific */

__asm __fastcall __based __inline __cdecl __stdcall

also in same old MSDN documenttion __cdecl

__cdecl Home | Overview | How Do I

Microsoft Specific —>

This is the default calling convention for C and C++ programs. Because the stack is cleaned up by the caller, it can do vararg functions. The __cdecl calling convention creates larger executables than __stdcall, because it requires each function call to include stack cleanup code. The following list shows the implementation of this calling convention.

otherwise, we all are lost in your question (please revise it) ;)

Pierette answered 3/11, 2021 at 21:29 Comment(0)
B
0

Updated I've totally revised this, after the comments pointing out how wrong I was. cdecl means that this function uses the same calling convention that C functions use. extern "C" means, in addition, that the function name should not undergo C++ name-mangling.

As for why it's called cdecl, I don't know any more.

Binnings answered 13/2, 2011 at 21:8 Comment(2)
extern "C" does not amount to the same thing as cdecl. You're making it up too!Tushy
C++ functions are also _cdecl (In fact that's the default on most compilers unless it's a nonstatic member function, in which case it's _thiscall)Inimical

© 2022 - 2024 — McMap. All rights reserved.