开发者

What does "cdecl" stand for?

Yes, I know that "cdecl" is the name of a prominent calling convention, so please don't 开发者_如何学Pythonexplain 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?


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.


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.


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


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)


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


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.


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.


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) ;)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜