“cdecl”是什么意思?代表?
是的,我知道“cdecl”是一个著名的调用约定的名称,所以请不要向我解释调用约定。我要问的是缩写(?)“cdecl”实际上代表什么。我认为这是一个糟糕的命名选择,因为乍一看它让人想起“C 声明符”(C 的一个相当独特的语法方面)。事实上,有一个名为 cdecl 的程序,其唯一目的是破译 C 声明符。但据我所知,C 声明符语法与调用约定完全无关。
简化版本:“stdcall”代表“标准调用约定”。 “cdecl”代表什么?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
它来自已声明的 C 函数(与 K&RC 中常见的未声明的 C 函数相反)。
当时它与 pascal 调用约定(被调用者清除堆栈)共存,因此在编程语言之后调用它是有意义的。
您可能想了解的有关调用约定的所有内容。
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.
你读得太多了。它代表一般调用 C 函数的实现的调用约定(但对于可变参数尤其重要)。
它不一定是“C”和“声明”组合的缩写;名字只是名字,尤其是在编程中。助记符很有帮助,但尽管“malloc”的意思是“分配内存”,但它还有我们知道并附加的附加含义;例如,“alloca”也“分配内存”。
或者采用“struct”,它“意味着”“结构”,但“结构”本身是如此通用,如果没有我们潜意识中赋予“结构”的含义,我们将无可救药地迷失——因为仍在学习术语的新程序员经常会迷失。
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 声明。由/为 C 引入的声明。
[编辑]
老实说,我必须承认我实际上不知道这是否代表什么,尽管它实际上是由/为 C 引入的。但是由于
调用者
必须清理分配的内存(与大多数其他调用约定相反)。它也可能是“来电者结束清洁”的助记符,我认为这实际上是一个很好的记忆帮助。 :DC 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. :DCDECL 一词源自 Microsoft 的 BASIC 及其混合语言编程生态系统。该生态系统允许 Microsoft 四种主要语言(BASIC、FORTRAN、Pascal 和 C)中的任何一种语言调用任何其他语言。每种语言的调用约定都略有不同,并且每种语言都有一种方法来声明使用特定约定的外部函数或过程。
在 BASIC 中,必须先使用
DECLARE
语句,然后才能使用CALL
语句调用外部函数。要表示外部 FORTRAN 或 Pascal 过程或函数,您将编写一种与其他语言不同的 C 调用约定,部分原因是参数以相反的顺序压入堆栈。您可以通过添加 CDECL 修饰符来通知 BASIC:
相反,当用 FORTRAN 或 Pascal 编写时,修饰符是 [C]。这表明 CDECL 特定于 BASIC 的 DECLARE 语句,而不是
先前确定的术语。当时,还没有“C 调用约定”的具体术语。只有随着 WIN32 中新的调用约定(stdcall、fastcall 等)的出现,“cdecl”才被增选并成为在没有其他术语的情况下引用旧约定的事实上的名称。
综上所述,CDECL的意思是“C声明”。它起源于 BASIC 编译器,而不是 C 编译器,并且它是任意选择的 BASIC 关键字,并且有些多余,因为普通的“C”不能是关键字。
有关 CDECL 的详细信息可以在 1987 年的文档中找到:
https: //archive.org/details/Microsoft_Macro_Assembler_5.1_Mixed_Language_Programming_Guide/page/n1/mode/2up?q=cdecl
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 theCALL
statement. To denote an external FORTRAN or Pascal procedure or function, you would write one ofC 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:
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
cdecl
(C 声明)调用约定通常是 x86 C 编译器的默认调用约定(来源)
调用约定可能与特定编程语言的评估策略,但大多数情况下不被视为其一部分(反之亦然),因为评估策略通常是在更高的抽象级别上定义的,并被视为语言的一部分,而不是特定的低级实现细节语言的编译器。
(来源)
cdecl
(代表 C 声明)是一种调用约定,源自 Microsoft 的 C 编程语言编译器,并被许多 x86 架构的 C 编译器使用。在cdecl
中,子例程参数在堆栈上传递。整数值和内存地址在EAX
寄存器中返回,浮点值在ST0
x87 寄存器中返回。寄存器EAX
、ECX
和EDX
由调用者保存,其余寄存器由被调用者保存。调用新函数时,x87 浮点寄存器ST0
至ST7
必须为空(弹出或释放),并且ST1
至ST7退出函数时
必须为空。当不用于返回值时,ST0
也必须为空。在 C 编程语言的上下文中,函数参数按从右到左的顺序压入堆栈,即最后一个参数首先压入。
考虑以下 C 源代码片段:
在 x86 上,它可能会生成以下汇编代码(Intel 语法):
调用者在函数调用返回后清理堆栈。
cdecl
调用约定通常是 x86 C 编译器的默认调用约定,尽管许多编译器提供了自动更改所使用的调用约定的选项。要手动将函数定义为cdecl
,有些支持以下语法:其他约定:
(来源)< /em>
The
cdecl
(C Declaration) calling convention is usually the default calling convention for x86 C compilers(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. Incdecl
, subroutine arguments are passed on the stack. Integer values and memory addresses are returned in theEAX
register, floating point values in theST0
x87 register. RegistersEAX
,ECX
, andEDX
are caller-saved, and the rest are callee-saved. The x87 floating point registersST0
toST7
must be empty (popped or freed) when calling a new function, andST1
toST7
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:
On x86, it might produce the following assembly code (Intel syntax):
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 becdecl
, some support the following syntax:Other Conventions:
(Source)
C 有函数和变量的概念,汇编程序/机器代码没有。当想要将值传递给函数时,需要使用 cpu 寄存器或内存中距离寄存器(通常是指定的堆栈指针)固定偏移量的值来完成。因此,当我们在函数开头跳转到新地址时,正确的值位于正确的位置,以便函数正确执行。这同样适用于返回值。
它在实践中如何工作在描述系统调用约定的文档中定义。调用约定对于 CPU 架构和操作系统来说都是独特的。
在 x86 Windows 上,使用了许多调用约定。在“cdecl”调用约定中,调用者将函数放在堆栈上供被调用者使用。一旦函数完成,调用者就会清理自己的堆栈。
Windows API 使用“stdcall”调用约定,该约定与 cdelc 类似,只是被调用者清理堆栈。 (这意味着无法使用vararg函数调用call)。它的优点是节省代码空间。
Windows 还有一个“fastcall”调用约定,它利用寄存器进行参数传递。
由于 Windows 允许多种调用约定,C 编译器 (cl) 通过
__cdecl
、__stdcall
和__fastcall
扩展了 C 语言。这装饰了函数声明并允许程序员指定所使用的调用约定。其他平台(如 ARM、Itanium 等)有自己的调用约定。
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.
CDECL没有缩写,它只是调用约定的名称。
如果这不是您要寻找的内容,那么实际上是 CDECL 的历史:
它是 Microsoft 特定的调用约定属性(在 1985 年到 1995 年之间引入),后来成为标准。
可惜页面从互联网上丢失了(回溯也什么也没有),但是谁有旧的 MSDN CD 可能会在“C 语言参考”中找到主题“声明摘要”,其中明确指出以下内容:
也在相同的旧 MSDN 文档 __cdecl 中
否则,我们都会迷失在你的问题中(请修改它);)
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:
also in same old MSDN documenttion __cdecl
otherwise, we all are lost in your question (please revise it) ;)
更新 在评论指出我的错误有多么严重之后,我已经完全修改了这一点。
cdecl
表示该函数使用与C
函数相同的调用约定。此外,extern "C"
还意味着函数名称不应进行C++
名称修改。至于为什么叫
cdecl
,我就不太清楚了。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 thatC
functions use.extern "C"
means, in addition, that the function name should not undergoC++
name-mangling.As for why it's called
cdecl
, I don't know any more.