在main之前调用的预定义函数

pre-defined function called before main

本文关键字:预定义 函数 调用 main      更新时间:2023-10-16

我不明白如何以及何时调用这个预定义函数sqrt(),而且如果我定义自己的函数sqrt(),它会显示编译错误,那么为什么预定义函数调用有效,而对用户定义函数的调用失败,尽管这两个代码都驻留在我的可执行文件的(TEXT)部分中。

#include<stdio.h>
int x = sqrt(16); 
int main()
{
printf(" x =  %dn",x);
return 0;
}

输出:

x = 4;

当我调用我定义的sqrt()函数时,我会得到以下错误,但当我使用预定义的函数时,相同的错误不会出现

错误:初始值设定项元素不是常量

如果您定义自己的sqrt函数,它将与math.h中已经定义的函数冲突,从而导致错误。

之所以进行调用,是因为全局变量(或者更确切地说,命名空间范围变量)在进入main之前进行了初始化——x的初始化即.

在C中,具有静态存储持续时间的变量的初始值设定项(这意味着它在程序的整个生命周期中都存在,例如您的x)必须是一个常量表达式。对函数的调用不是常量表达式,您将得到编译器错误,例如(来自GCC)错误:initializer元素不是常量。该标准还规定,"一个实现可以接受其他形式的常量表达式",因此允许编译器接受对库函数(如sqrt)的调用作为常量表达式。编译器知道sqrt将执行什么操作,甚至可以在编译过程中对其进行评估,并用其结果替换函数调用。

C++有不同的规则,在初始化x时,可以调用函数,甚至是您自己的函数。

Gcc编译器以过程的方式编译源文件。

使用g++或c++编译器。该代码将完美工作

我使用g++编译器编译了代码,编译成功。

#include<stdio.h>
int mysqrt(int n)
{
return(n);
}
int a=mysqrt(10);
int main()
{
printf("%d",a);
return(0);
}

请忽略mysqrt函数的内部逻辑。这只是为了测试目的。

据我所知,这是gcc编译器的一个问题。

标准第6.6条第3款规定

常量表达式不应包含赋值、增量、,递减运算符、函数调用运算符或逗号运算符,除非它们是包含在未计算的子表达式中。

常量表达式不能包含要计算的函数调用。

这是因为

常量表达式可以在翻译过程中求值,而不是运行时,因此可以在常量可以使用的任何地方使用是

gcc编译器能够通过在编译时执行库函数来计算常量表达式。但它无法通过在编译时执行用户定义的函数来计算常量表达式。但是g++和c++编译器能够完成这项工作。

它说一个名为sqrt()的函数已经定义为其他函数(math.h有它的声明)

当您添加math.h头文件时,它包含sqrt()函数的声明,该函数位于链接时将添加的库中。

当你试图用相同的名称定义你自己的函数时,编译器会混淆该调用哪个函数(你的函数或已经在math.h中声明的函数)

将函数名更改为my_sqrt(),在定义和调用时应该可以正常工作。

注意:试着了解一下调试过程。每个阶段发生的事情,你会更好地了解正在发生的事情。

您得到的错误是由Luchian上面解释的原因引起的。

为了准确地处理您的问题,您需要了解预处理器指令

预处理器指令是程序代码中包含的行前面有一个散列号(#)。这些行不是程序语句而是用于预处理器的指令。预处理器检查在代码的实际编译开始并解决所有这些问题之前任何代码实际由正则表达式生成之前的指令声明。

在进入主功能之前,您可以通过以下方式简单地定义x:

#define x BLAH

我想这会澄清你的一些想法。干杯!

尝试在另一个文件中定义函数,并在此处包含该文件。或者在初始化之前简单地声明函数