我遇到过以下代码:
typedef struct {
double x;
double y;
double z;
} *vector;
Run Code Online (Sandbox Code Playgroud)
这是一个有效的类型定义吗?代码编译并运行正常.如果这是常见做法,我只是好奇.
考虑这个例子:
#include <iostream>
class A {
public:
virtual void f();
};
void A::f()
{
std::cout << "f() from A\n";
}
class B: public A {
public:
virtual void f() = 0;
};
class C: public B {
public:
void f();
};
void C::f()
{
std::cout << "f() from C\n";
}
int main()
{
C o;
o.f();
}
Run Code Online (Sandbox Code Playgroud)
A::f()实现从C类"隐藏",它提供了自己的实现f()- 有效地使A::f()或多或少无意义.我认为这种类层次结构设计没什么价值,但我的问题是这是一个有效的C++还是只是"有效"(例如未定义的行为)?
翻译单元的常用定义是预处理之后(头文件包含,宏等与源文件一起).这个定义相当清楚,C标准5.1.1.1,C11说:
AC程序不需要全部同时翻译.该程序的文本保存在本国际标准中称为源文件(或预处理文件)的单元中.源文件以及通过预处理指令包含的所有头文件和源文件
#include称为预处理转换单元.在预处理之后,预处理翻译单元被称为翻译单元.
更仔细地阅读第一句话:
AC程序不需要全部同时翻译.
这意味着(对我来说),C程序可以在同一个程序中进行翻译,而不必将它们分成多个预处理源文件.同样在同一段的末尾,标准说:
翻译单元可以单独翻译,然后链接以产生可执行程序.
可以(通常是)解释为编译单个目标文件,然后最终链接它们以生成单个可执行程序.但是,如果可以从上述语句中提出问题并询问:这是否意味着实现可以自由地将多个源文件视为单个翻译单元,尤其是对于以下调用:
gcc file1.c file2.c -o out
Run Code Online (Sandbox Code Playgroud)
编译器可以访问整个源?
特别是,如果某个实现将file1.c+ file2.c(上述)视为单个翻译单元,是否可以将其视为不合格?
考虑一下代码片段:
int main(void)
{
int i = 42;
int *p = &i;
++p; // Is this pointer evaluation undefined?
*p = 5; // How about this?
return 0;
}
Run Code Online (Sandbox Code Playgroud)
指针的评估++p是不正确的?
C标准(C11,6.5.6)允许评估指向数组对象的一个末端的指针?这是否也适用于非数组对象?