What does "cdecl" stand for?

14,861

Solution 1

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

Solution 2

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.

Solution 3

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.

Solution 4

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

Solution 5

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)

Share:
14,861
fredoverflow
Author by

fredoverflow

Updated on June 04, 2022

Comments

  • fredoverflow
    fredoverflow almost 2 years

    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?

  • David Heffernan
    David Heffernan about 13 years
    +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!! ;-)
  • GolezTrol
    GolezTrol about 13 years
    And that's why I didn't enter my IP address in my profile. ;-)
  • David Heffernan
    David Heffernan about 13 years
    You should do the decent thing and give back all that rep!
  • David Heffernan
    David Heffernan about 13 years
    extern "C" does not amount to the same thing as cdecl. You're making it up too!
  • GolezTrol
    GolezTrol about 13 years
    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.
  • David Heffernan
    David Heffernan about 13 years
    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.
  • Billy ONeal
    Billy ONeal about 13 years
    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)
  • fredoverflow
    fredoverflow about 13 years
    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 :-(
  • GolezTrol
    GolezTrol about 13 years
    @FredOverflow. Didn't think of that. :-/
  • fredoverflow
    fredoverflow about 13 years
    I'm sure the linked PDF is an interesting read, but it doesn't answer my question.
  • GolezTrol
    GolezTrol about 13 years
    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.
  • Johannes Schaub - litb
    Johannes Schaub - litb about 13 years
    @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 char
  • Peer Stritzinger
    Peer Stritzinger about 13 years
    @FredOverflow: the link was only added as an extra info source.
  • Peer Stritzinger
    Peer Stritzinger about 13 years
    @litb: yeah exactly what I'm meaning, thanks for the clarifying example
  • Peer Stritzinger
    Peer Stritzinger about 13 years
    But only it does mean something ... see my answer
  • Fred Nurk
    Fred Nurk about 13 years
    @PeerStritzinger: I didn't say it means nothing, but, uh, thanks for the downvote because you misunderstood.
  • Fred Nurk
    Fred Nurk about 13 years
    @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.
  • Johannes Schaub - litb
    Johannes Schaub - litb about 13 years
    @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.
  • Fred Nurk
    Fred Nurk about 13 years
    @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.
  • Johannes Schaub - litb
    Johannes Schaub - litb about 13 years
    @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.
  • Peer Stritzinger
    Peer Stritzinger almost 13 years
    Hm how about telling why the -1, having something to share to improve the answer?
  • Support Ukraine
    Support Ukraine over 2 years
    I wonder which answer you want to reward. After all the only answer putting it clear (i.e. cdecl == C declaration) is your own ....
  • GolezTrol
    GolezTrol over 2 years
    I was hoping for a more conclusive answer, since this is declared nonsense :0
  • Support Ukraine
    Support Ukraine over 2 years
    Well the text says " reward an existing answer" Not looking for new answers
  • Hans Olsson
    Hans Olsson over 2 years
    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?
  • user2357112
    user2357112 over 2 years
    This answer is responding to an etymology question with a definition. Yes, words have meanings beyond their etymology, but they still have etymologies too.
  • GolezTrol
    GolezTrol over 2 years
    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 :D