来自 C 的指令 #include 和来自 C++ 的指令之间有什么区别吗?
Is there any difference between the directive #include from C and the one from C++?
这个问题在post中没有回答 #include <filename>
和#include “filename”
有什么区别? 这是一个不同的问题。
我正在研究 C 和 C++ 之间的差异。我通过比较您可以用每种语言制作的最基本的程序来做到这一点:
在 C 中:
#include <stdio.h>
int main()
{
printf("Hello World");
return 0;
}
在 C++ 中
#include <iostream>
int main()
{
std::cout << "Hello World!!!" << std::endl;
return 0;
}
我知道 headers 和编译过程。但我想知道 C 和 C++ 的 #include 指令之间是否有任何区别。例如,复制时的 header 内容可能以不同的方式复制。
我觉得这个问题很简单,你可以用"No"或者"yes, here are the differences: 1), 2)".
来回答
Like for example maybe the header content when is copied is copied in a different way.
#include
预处理器指令由 CPP 预处理器处理,即(大部分)与 C 和 C++ 编译相同。不同的 C 和 C++ 标准可能会引入 subtle differences, but none of these affects how the #include
directive should be handled regarding how the file's content is replaced into the translation unit (besides how the header file names are expanded and matched, see @T.C.'s ).
CPP 仅进行文本替换,并将从包含的文件中看到的内容扩展到翻译单元中,无论是 C 还是 C++ 代码。
I think this question is very straightforward, you can answer it by saying "No" or "yes, here are the differences: 1), 2)".
不,#include
指令在文本替换方面没有区别。
嗯,从结果来看,C 编译器可能无法正确编译从 C++ 头文件展开的代码,有时反之亦然。
是的,至少有两点不同。在 C++ 中(WG21 N4567 [cpp.include]/5):
The implementation shall provide unique mappings for sequences
consisting of one or more nondigits or digits (2.10) followed by a
period (.
) and a single nondigit. The first character shall not be
a digit. The implementation may ignore distinctions of alphabetical
case.
在 C 中(WG14 N1570 6.10.2/5,强调我的):
The implementation shall provide unique mappings for sequences
consisting of one or more nondigits or digits (6.4.2.1) followed by a
period (.
) and a single nondigit. The first character shall not be a
digit. The implementation may ignore distinctions of alphabetical case
and restrict the mapping to eight significant characters before the
period.
符合标准的 C 实现可以将“foobarbaz.h
”和“foobarbat.h
”映射到同一个源文件。符合标准的 C++ 实现不能。
此外,在 C (N1570 6.4.7) 中:
If the characters '
, \
, "
, //
, or /*
occur in the sequence
between the <
and >
delimiters, the behavior is undefined.
Similarly, if the characters '
, \
, //
, or /*
occur in the
sequence between the "
delimiters, the behavior is undefined.
在 C++ 中 (N4567 [lex.header]/2):
The appearance of either of the characters '
or \
or of either of
the character sequences /*
or //
in a q-char-sequence or an
h-char-sequence is conditionally-supported with implementation-defined semantics, as is the appearance of the
character "
in an h-char-sequence.
"conditionally-supported with implementation-defined semantics" 表示
- 如果实现不支持它,它必须发出诊断;
- 如果实现确实支持它,则必须记录它对该构造的解释。
而"undefined behavior"意味着实现可以为所欲为。
在 C++ 中,通常会搜索更多目录。不过,这在技术上与 指令 没有区别。
例如,在我的系统上:
% gcc -E -v -x c - <<< '' 2>&1 | sed -n '/cc1/,/End of search list/p'
/usr/lib/gcc/x86_64-linux-gnu/5/cc1 -E -quiet -v -imultiarch x86_64-linux-gnu - -mtune=generic -march=x86-64
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/5/../../../../x86_64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/lib/gcc/x86_64-linux-gnu/5/include
/usr/local/include
/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed
/usr/include/x86_64-linux-gnu
/usr/include
End of search list.
% gcc -E -v -x c++ - <<< '' 2>&1 | sed -n '/cc1/,/End of search list/p'
/usr/lib/gcc/x86_64-linux-gnu/5/cc1plus -E -quiet -v -imultiarch x86_64-linux-gnu -D_GNU_SOURCE - -mtune=generic -march=x86-64
ignoring duplicate directory "/usr/include/x86_64-linux-gnu/c++/5"
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/5/../../../../x86_64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/include/c++/5
/usr/include/x86_64-linux-gnu/c++/5
/usr/include/c++/5/backward
/usr/lib/gcc/x86_64-linux-gnu/5/include
/usr/local/include
/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed
/usr/include/x86_64-linux-gnu
/usr/include
End of search list.
此外,不涉及#include
的预处理器之间存在差异:
- 命名运算符是 C++ 中内置的。在 C 中,您必须
#include <iso646.h>
- 布尔关键字是 C++ 内置的。在 C 中,您必须
#include <stdbool.h>
- 自 C++14 起,
'
可用作数字分隔符。 (普遍认为这是个坏主意,但委员会不会接受其他任何东西)。
这个问题在post中没有回答 #include <filename>
和#include “filename”
有什么区别? 这是一个不同的问题。
我正在研究 C 和 C++ 之间的差异。我通过比较您可以用每种语言制作的最基本的程序来做到这一点:
在 C 中:
#include <stdio.h>
int main()
{
printf("Hello World");
return 0;
}
在 C++ 中
#include <iostream>
int main()
{
std::cout << "Hello World!!!" << std::endl;
return 0;
}
我知道 headers 和编译过程。但我想知道 C 和 C++ 的 #include 指令之间是否有任何区别。例如,复制时的 header 内容可能以不同的方式复制。 我觉得这个问题很简单,你可以用"No"或者"yes, here are the differences: 1), 2)".
来回答Like for example maybe the header content when is copied is copied in a different way.
#include
预处理器指令由 CPP 预处理器处理,即(大部分)与 C 和 C++ 编译相同。不同的 C 和 C++ 标准可能会引入 subtle differences, but none of these affects how the #include
directive should be handled regarding how the file's content is replaced into the translation unit (besides how the header file names are expanded and matched, see @T.C.'s
CPP 仅进行文本替换,并将从包含的文件中看到的内容扩展到翻译单元中,无论是 C 还是 C++ 代码。
I think this question is very straightforward, you can answer it by saying "No" or "yes, here are the differences: 1), 2)".
不,#include
指令在文本替换方面没有区别。
嗯,从结果来看,C 编译器可能无法正确编译从 C++ 头文件展开的代码,有时反之亦然。
是的,至少有两点不同。在 C++ 中(WG21 N4567 [cpp.include]/5):
The implementation shall provide unique mappings for sequences consisting of one or more nondigits or digits (2.10) followed by a period (
.
) and a single nondigit. The first character shall not be a digit. The implementation may ignore distinctions of alphabetical case.
在 C 中(WG14 N1570 6.10.2/5,强调我的):
The implementation shall provide unique mappings for sequences consisting of one or more nondigits or digits (6.4.2.1) followed by a period (
.
) and a single nondigit. The first character shall not be a digit. The implementation may ignore distinctions of alphabetical case and restrict the mapping to eight significant characters before the period.
符合标准的 C 实现可以将“foobarbaz.h
”和“foobarbat.h
”映射到同一个源文件。符合标准的 C++ 实现不能。
此外,在 C (N1570 6.4.7) 中:
If the characters
'
,\
,"
,//
, or/*
occur in the sequence between the<
and>
delimiters, the behavior is undefined. Similarly, if the characters'
,\
,//
, or/*
occur in the sequence between the"
delimiters, the behavior is undefined.
在 C++ 中 (N4567 [lex.header]/2):
The appearance of either of the characters
'
or\
or of either of the character sequences/*
or//
in a q-char-sequence or an h-char-sequence is conditionally-supported with implementation-defined semantics, as is the appearance of the character"
in an h-char-sequence.
"conditionally-supported with implementation-defined semantics" 表示
- 如果实现不支持它,它必须发出诊断;
- 如果实现确实支持它,则必须记录它对该构造的解释。
而"undefined behavior"意味着实现可以为所欲为。
在 C++ 中,通常会搜索更多目录。不过,这在技术上与 指令 没有区别。
例如,在我的系统上:
% gcc -E -v -x c - <<< '' 2>&1 | sed -n '/cc1/,/End of search list/p'
/usr/lib/gcc/x86_64-linux-gnu/5/cc1 -E -quiet -v -imultiarch x86_64-linux-gnu - -mtune=generic -march=x86-64
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/5/../../../../x86_64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/lib/gcc/x86_64-linux-gnu/5/include
/usr/local/include
/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed
/usr/include/x86_64-linux-gnu
/usr/include
End of search list.
% gcc -E -v -x c++ - <<< '' 2>&1 | sed -n '/cc1/,/End of search list/p'
/usr/lib/gcc/x86_64-linux-gnu/5/cc1plus -E -quiet -v -imultiarch x86_64-linux-gnu -D_GNU_SOURCE - -mtune=generic -march=x86-64
ignoring duplicate directory "/usr/include/x86_64-linux-gnu/c++/5"
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/5/../../../../x86_64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/include/c++/5
/usr/include/x86_64-linux-gnu/c++/5
/usr/include/c++/5/backward
/usr/lib/gcc/x86_64-linux-gnu/5/include
/usr/local/include
/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed
/usr/include/x86_64-linux-gnu
/usr/include
End of search list.
此外,不涉及#include
的预处理器之间存在差异:
- 命名运算符是 C++ 中内置的。在 C 中,您必须
#include <iso646.h>
- 布尔关键字是 C++ 内置的。在 C 中,您必须
#include <stdbool.h>
- 自 C++14 起,
'
可用作数字分隔符。 (普遍认为这是个坏主意,但委员会不会接受其他任何东西)。