简体   繁体   English

哪些是可执行语句?

[英]Which are the executable statements?

Many times, reading around, I found definitions like this one: 很多时候,阅读,我发现这样的定义:

Definitions are not executable statements. 定义不是可执行语句。 They're messages to the compiler. 它们是编译器的消息。 For example, the definition int i; 例如,定义int i; simply tells the compiler the type of variable i and instructs the compiler to reserve space in memory for the variable. 只是告诉编译器变量i的类型,并指示编译器在内存中为变量保留空间。

Statements like this one leave me always confused, because, IMHO, everything can be seem as "requiring an action". 像这样的陈述让我总是感到困惑,因为,恕我直言,一切都可以看作“需要行动”。 For example, in this case, the computer has to perform some actions to allocate some memory. 例如,在这种情况下,计算机必须执行一些操作来分配一些内存。

So what are those statements really referring to? 那些真正指称的陈述是什么?

C language recognizes the similarity between local declarations and statements . C语言识别本地声明和语句之间的相似性。 This is reflected in 这体现在

6.8 Statements and blocks 6.8声明和块

3 A block allows a set of declarations and statements to be grouped into one syntactic unit. 3块允许将一组声明和语句分组为一个语法单元。 The initializers of objects that have automatic storage duration, and the variable length array declarators of ordinary identifiers with block scope, are evaluated and the values are stored in the objects (including storing an indeterminate value in objects without an initializer) each time the declaration is reached in the order of execution, as if it were a statement , and within each declaration in the order that declarators appear. 具有自动存储持续时间的对象的初始化程序和具有块作用域的普通标识符的可变长度数组声明符将被评估,并且每次声明时,值都存储在对象中(包括在没有初始化程序的对象中存储不确定值)按执行顺序到达, 就好像它是一个语句 ,并在声明符出现的顺序中的每个声明中。

However, formally, declarations are not classified as statements in C. 但是,正式地说,声明在C中不被归类为声明。

Note that "statement-ish" properties of a local declarations are actually tied to initialization. 请注意,本地声明的“statement-ish”属性实际上与初始化有关。 As for memory allocation... the language does not actually specify when exactly that memory allocation occurs. 至于内存分配......语言实际上并没有指定何时发生内存分配。 It does not necessarily occur when control passes over the definition. 当控制遍历定义时,不一定会发生这种情况。

External definitions are definitely not statements since they are not involved in the control flow. 外部定义绝对不是语句,因为它们不参与控制流程。

Imagine getting a new car from a car dealer. 想象一下从汽车经销商那里买一辆新车。 They will show you where the switches for the headlights are, how the gears are arranged and how to open the trunk. 它们将向您显示前大灯的开关,齿轮的排列方式以及如何打开行李箱。 This is all declarative. 这都是声明性的。 Nothing is actually happening. 什么都没发生。 In terms of a compiler: no output will be created. 就编译器而言:不会创建任何输出。

Once you start using the car, you will perform different actions according to the knowledge you've been given. 一旦您开始使用汽车,您将根据您获得的知识执行不同的操作。 You will shift gears accordingly and use the proper switch to turn on the headlights. 您将相应地换档并使用正确的开关打开前灯。 In terms fo a compiler: the compiled output will vary depending on the declarations given beforehand. 就编译器而言:编译后的输出将根据事先给出的声明而变化。

Compilers translate the C language into machine code, which can be executed by the CPU. 编译器将C语言转换为机器代码,可以由CPU执行。 It's often easy to see which bytes of machine code correspond to which statements in your C code. 通常很容易看出哪些字节的机器代码与C代码中的哪些语句相对应。 Debuggers use this correspondence when showing how your C code runs. 在显示C代码的运行方式时,调试器使用此对应关系。

So the meaning of "a declaration is not an executable statement" is that no machine code corresponds to a declaration. 因此,“声明不是可执行语句”的含义是没有机器代码对应于声明。 This also means that: 这也意味着:

  • CPU doesn't spend any time to "run" the declaration (but the compiler does spend time to examine it) CPU不花任何时间“运行”声明(但编译器确实花时间检查它)
  • A visual debugger will "skip" the declaration when running your program step by step 在逐步运行程序时,可视化调试器将“跳过”声明

You can see this in the online compiler explorer , which does this for C++, but it's close enough to C. It paints each line of code in a different colour to visualize which lines generate which machine code. 您可以在在线编译器资源管理器中看到这一点,它可以用于C ++,但它与C足够接近。它以不同的颜色绘制每行代码,以可视化哪些行生成哪些机器代码。 An example from there: 一个例子:

Input C/C++ code 输入C / C ++代码

int square(int num)             // painted in white
{                               // painted in teal
    int result;                 // painted in white
    result = num * num;         // painted in yellow
    return result;              // painted in gray
}                               // painted in red

Output assembly code (represents machine code) 输出汇编代码(代表机器代码)

square(int):
        push    rbp                          // painted in green
        mov     rbp, rsp                     // painted in green
        mov     DWORD PTR [rbp-20], edi      // painted in green
        mov     eax, DWORD PTR [rbp-20]      // painted in yellow
        imul    eax, DWORD PTR [rbp-20]      // painted in yellow
        mov     DWORD PTR [rbp-4], eax       // painted in yellow
        mov     eax, DWORD PTR [rbp-4]       // painted in gray
        pop     rbp                          // painted in red
        ret                                  // painted in red

You can see that lines painted in white (declarations) "don't generate code", and "are not executable statements". 您可以看到以白色绘制的线条(声明)“不生成代码”,“不是可执行语句”。


The "not executable" idea is not a hard rule; “不可执行”的想法不是一个硬性规则; just a guideline. 只是一个指导方针。 Some situations where a declaration is "executable": 声明为“可执行”的某些情况:

int x = 0; // a trivial calculation, but it will appear in machine code
int y = x * (x + 1); // a non-trivial calculation
int a[rand() % 10 + 1]; // possible without initialization too (suggested by by user AnT)

In the impreative programming paradigm, a statement is a description of what and how the program should take an action , while a declaration is a description of what the tools the program should use . 在创造性的编程范例中,声明是对程序应采取何种行动以及如何采取行动的描述,而声明则是对程序应该使用的工具的描述。 The line int i only declares that the program requires an object of type (int), and the line int i = 0 declares that the program requires an object of type (int) with an initial value of zero. int i仅声明程序需要类型为(int)的对象,而行int i = 0声明程序需要类型为(int)的对象,初始值为零。 None of those are statements, even both could require action from the program. 这些都不是陈述,即使两者都需要该计划采取行动。

You are right that every line of code could potentially (1) involve some "execution" from the program. 你是对的,每一行代码都可能 (1)涉及程序的一些“执行”。 But the distinction is about what the language is, as a description of algorithms, not how it is implemented in real-world machines. 但区别在于语言是什么,作为算法的描述,而不是如何在现实世界的机器中实现。

(1): any declaration or statement can be optimized-out, for instance (1):例如,任何声明或声明都可以进行优化

int i; in the global context or static int i; 在全局上下文中或static int i; anywhere reserve space for i and zero-initialize it. 在任何地方为i保留空间并对其进行零初始化。 These allocations are typically glued with other allocations and done in one fell swoop when the program is loaded. 这些分配通常与其他分配相关联,并在加载程序时一举完成。

int i inside a function does potentially nothing if you don't use the variable. 如果不使用变量,函数内部的int i可能没有任何作用。 If you do use it, the compiler will try to use it as an alias for a CPU register. 如果您使用它,编译器将尝试将其用作CPU寄存器的别名。 If all registers are taken and an old register variable cannot be reused or if you take the address of the variable, the compiler will need to spill the variable into the stack. 如果采用所有寄存器并且无法重用旧的寄存器变量,或者如果获取变量的地址,则编译器将需要将变量溢出到堆栈中。 All the stack variables of a function will typically be allocated upon entering the function, all at once, and the allocation will be done by incrementing (/decrementing) the stack pointer (in a register, hidden from you when you're in C). 函数的所有堆栈变量通常在进入函数时一次性分配,并且分配将通过递增(/递减)堆栈指针(在寄存器中,当你在C中时隐藏)来完成。 In essence, the CPU-time cost of allocating an automatic variable will be at most a fraction of the time it takes to subtract an integer. 实质上,分配自动变量的CPU时间成本最多只是减去整数所需时间的一小部分。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何为从中获取可执行文件的.c查找? - How To find .c for the executable from which it is obtained? a.out linux可执行文件是哪个程序的? - a.out linux executable is of which program? C中的单行if语句-哪些语句会受到影响? - Single-line if statements in C - which statements are affected? 多个#ifndef语句-应用哪一个 - Multiple #ifndef statements - which one gets applied 哪个更快:空函数调用或如果语句? - Which is faster: Empty Function Call or If Statements? 为什么可执行文件小于与应用程序项目静态链接的库? - why executable is smaller than the library which is statically linked with application project? 如何在与Windows 7不兼容的cmd中运行可执行文件? - how to run an executable file in cmd which is incompatible with windows 7? 如何确定使用了哪个编译器来编译可执行文件? - How to determine which compiler has been used to compile an executable? 生成映射文件,该文件显示可执行文件中各个组件的内存范围 - Generating map file which shows memory range of individual components in an executable 返回语句的表达式结果存储在 memory 的哪一部分? - which part of the memory does the result of the expression of the return statements gets stored in?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM