我知道 ODR、链接、static和如何extern "C"与函数配合使用。但我不确定类型的可见性,因为它们无法声明static,并且 C 中没有匿名名称空间。
特别是,我想知道以下代码如果编译为 C 和 C++ 的有效性
// A.{c,cpp}
typedef struct foo_t{
int x;
int y;
} Foo;
static int use_foo()
{
Foo f;
f.x=5;
return f.x;
}
Run Code Online (Sandbox Code Playgroud)
// B.{c,cpp}
typedef struct foo_t{
double x;
} Foo;
static int use_foo()
{
Foo f;
f.x=5.0;
return f.x;// Cast on purpose
}
Run Code Online (Sandbox Code Playgroud)
使用以下两个命令(我知道两个编译器都会根据扩展自动检测语言,因此名称不同)。
g++ -std=c++17 -pedantic -Wall -Wextra a.cpp b.cppgcc -std=c11 -pedantic -Wall -Wextra a.c b.c8.3 版本可以愉快地编译两者,没有任何错误。显然,如果两个结构符号都具有外部链接,则存在 ODR 违规,因为定义不相同。是的,编译器不需要报告它,因此我的问题是因为两者都没有报告。
假设我有两个翻译单元:
//A.cpp
class X
{
};
//B.cpp
class X
{
int i;
};
Run Code Online (Sandbox Code Playgroud)
上面的程序是否格式良好?
如果没有,没有进一步的问题。如果答案是肯定的,程序是良构的(忽略 main 的缺失),那么第二个问题。如果其中有一个同名的函数怎么办?
//A.cpp
class X
{
void f(){}
};
//B.cpp
class X
{
int i;
void f(){}
};
Run Code Online (Sandbox Code Playgroud)
这对链接器来说会不会是一个问题,因为它会在两个目标文件中看到 &X::f ?在这种情况下必须使用匿名命名空间吗?
请考虑以下示例:
// usedclass1.hpp
#include <iostream>
class UsedClass
{
public:
UsedClass() { }
void doit() { std::cout << "UsedClass 1 (" << this << ") doit hit" << std::endl; }
};
// usedclass2.hpp
#include <iostream>
class UsedClass
{
public:
UsedClass() { }
void doit() { std::cout << "UsedClass 2 (" << this << ") doit hit" << std::endl; }
};
// object.hpp
class Object
{
public:
Object();
};
// object.cpp
#include "object.hpp"
#include "usedclass2.hpp"
Object::Object()
{
UsedClass b;
b.doit();
}
// …Run Code Online (Sandbox Code Playgroud)