两个文件中相同函数/全局变量的不同声明

Que*_*tin 6 c c++ function global-variables forward-declaration

在C和C++的情况下,我有两个关于同一函数和全局变量的声明的两个问题.

  1. 不同的函数声明

    请考虑以下代码片段:

    file_1.c

    void foo(int a);
    
    int main(void)
    {
        foo('A');
    }
    
    Run Code Online (Sandbox Code Playgroud)

    file_2.c

    #include <stdio.h>
    
    void foo(char a)
    {
        printf("%c", a); //prints 'A' (gcc)
    }
    
    Run Code Online (Sandbox Code Playgroud)

    我们可以看到,原型与file_2.c中的定义不同 ,但是,该函数会打印预期值.

    如果是C++,由于foo(int)链接时未定义的引用,上述程序无效.它可能是由其他函数签名的存在引起的 - 与C相比,其中函数名称不包含任何指示函数参数类型的额外字符.

    但是当涉及到C然后是什么?由于具有相同名称的原型具有相同的签名,无论参数的数量及其类型如何,链接器都不会发出错误.但是在这里执行哪种类型的转换?它看起来像这样:'A'- > int- >回到char?或者这种行为可能未定义/实现定义?

  2. 全局变量的不同声明

    我们有两个文件和两个不同的同一个全局变量的声明:

    file_1.c

    #include <stdio.h>
    
    extern int a;
    
    int main(void)
    {
        printf("%d", a); //prints 65 (g++ and gcc)
    }
    
    Run Code Online (Sandbox Code Playgroud)

    file_2.c

    char a = 'A';
    
    Run Code Online (Sandbox Code Playgroud)

    在C和C++中,输出都是65.

    虽然我想知道两种标准对这种情况的看法.

    在C11标准中,我发现了以下片段:

    J.5.11多个外部定义 (附件J.5公共扩展)
    对象的标识符可能有多个外部定义,有或没有明确使用关键字extern; 如果定义不一致,或者初始化了多个,则行为未定义(6.9.2).

    请注意,它指的是两个或更多定义的存在,在我的代码中只有一个,所以我不确定这篇文章在这种情况下是否是一个很好的参考点...

das*_*ght 5

Q1.根据C99规范,第6.5.2.2.9节,它是C中未定义的行为:

如果函数定义的类型与表示被调用函数的表达式指向的类型(表达式)不兼容,则行为未定义.

表达"指向"一个函数取一个int,而函数定义为取一个char.

Q2.变量的情况也是未定义的行为,因为您正在阅读或指定一个int/从char.假设4字节整数,这将访问超过其有效的内存位置的三个字节.您可以通过声明更多变量来测试这一点,如下所示:

char a = 'A';
char b = 'B';
char c = 'C';
char d = 'D';
Run Code Online (Sandbox Code Playgroud)