41

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
  • 601,492
  • 42
  • 1,072
  • 1,490
fredoverflow
  • 256,549
  • 94
  • 388
  • 662
  • 2
    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. – Anon. Feb 13 '11 at 21:04
  • "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. – Steve Jessop Feb 13 '11 at 21:05
  • 5
    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... – R.. GitHub STOP HELPING ICE Feb 14 '11 at 01:05
  • 1
    @R..: yes, it pretty much disproves the dot-com prediction of java making Windows irrelevant. – MSalters Feb 14 '11 at 10:03
  • 3
    @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? – fredoverflow Feb 14 '11 at 16:58
  • 6
    @R.. Windows development resources are fantastic. I suspect you are spouting off from a position of some ignorance on this particular topic. – David Heffernan Feb 14 '11 at 17:18
  • 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" ` – daparic May 07 '20 at 17:21
  • Yes, this is why I "love" c / c++ that much – marsh-wiggle Nov 01 '21 at 17:47

8 Answers8

33

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.

Peer Stritzinger
  • 8,232
  • 2
  • 30
  • 43
  • 3
    I'm sure the linked PDF is an interesting read, but it doesn't answer my question. – fredoverflow Feb 13 '11 at 21:35
  • 4
    @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` – Johannes Schaub - litb Feb 13 '11 at 23:36
  • @FredOverflow: the link was only added as an extra info source. – Peer Stritzinger Feb 14 '11 at 13:17
  • @litb: yeah exactly what I'm meaning, thanks for the clarifying example – Peer Stritzinger Feb 14 '11 at 13:18
  • 5
    @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. – Fred Nurk Feb 14 '11 at 14:13
  • @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. – Johannes Schaub - litb Feb 14 '11 at 19:08
  • 1
    @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. – Fred Nurk Feb 14 '11 at 20:08
  • @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. – Johannes Schaub - litb Feb 15 '11 at 00:34
  • Hm how about telling why the -1, having something to share to improve the answer? – Peer Stritzinger May 15 '11 at 12:21
  • 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? – Hans Olsson Nov 03 '21 at 11:12
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.

Fred Nurk
  • 13,952
  • 4
  • 37
  • 63
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

Ramon Zarazua B.
  • 7,195
  • 4
  • 22
  • 26
GolezTrol
  • 114,394
  • 18
  • 182
  • 210
  • 3
    +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!! ;-) – David Heffernan Feb 13 '11 at 21:12
  • And that's why I didn't enter my IP address in my profile. ;-) – GolezTrol Feb 13 '11 at 21:15
  • You should do the decent thing and give back all that rep! – David Heffernan Feb 13 '11 at 21:18
  • 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. – GolezTrol Feb 13 '11 at 21:24
  • 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. – David Heffernan Feb 13 '11 at 21:30
  • 5
    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 :-( – fredoverflow Feb 13 '11 at 21:32
  • @FredOverflow. Didn't think of that. :-/ – GolezTrol Feb 13 '11 at 21:33
  • 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. – GolezTrol Feb 13 '11 at 22:02
  • 1
    I wonder which answer you want to reward. After all the only answer putting it clear (i.e. cdecl == **C decl**aration) is your own .... – Support Ukraine Oct 30 '21 at 01:04
  • I was hoping for a more conclusive answer, since this is declared nonsense :0 – GolezTrol Oct 31 '21 at 19:57
  • Well the text says " reward an existing answer" Not looking for new answers – Support Ukraine Nov 02 '21 at 18:49
  • 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 – GolezTrol Nov 09 '21 at 13:24
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)

Felix Quehl
  • 744
  • 1
  • 9
  • 24
4

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

Curt
  • 470
  • 3
  • 7
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.

Eric Aya
  • 69,473
  • 35
  • 181
  • 253
doron
  • 27,972
  • 12
  • 65
  • 103
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) ;)

SoLaR
  • 778
  • 7
  • 22
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.

TonyK
  • 16,761
  • 4
  • 37
  • 72