在编译C ++源文件时,如果您有多个包含方括号和带引号的标题的标头,是否必须始终首先列出方括号的标头?
我在带括号的标题之前放置了带引号的标题,这开始给我重新定义编译器错误。
头文件(utilities.h)是:
#ifndef _UTILITIES_H
#define _UTILITIES_H
#include <vector>
double calcNorm(std::vector <double> array); //template?
#endif
源文件(utilities.cpp)是
#include <math.h>
#include <vector>
#include "utilities.h"
double calcNorm(std::vector <double> array) //template?
{
int n;
double norm = 0;
n = array.size();
for (int i = 0; i < n; i++)
{
norm += array[i]*array[i];
}
norm = sqrt(norm);
return norm;
}
以前,在源文件中,我将#include "utilities.h"
放在方括号标题的上方,并且遇到以下编译器错误:
g++ -g -Wall -c utilities.cpp
utilities.cpp: In function ‘double calcNorm(std::vector<double>)’:
utilities.cpp:5:8: error: redefinition of ‘double calcNorm(std::vector<double>)’
double calcNorm(std::vector <double> array) //template?
^
utilities.h:3:8: note: ‘double calcNorm(std::vector<double>)’ previously defined here
makefile:12: recipe for target 'utilities.o' failed
答案 0 :(得分:4)
在编译C ++源文件时,如果您有多个包含方括号和带引号的标题的标头,是否必须始终首先列出方括号的标头?
否。
头文件(在源文件中以及在其他头文件中)可以任意顺序。实际上,只要每个头文件位于依赖于头声明的任何声明之前,甚至不需要在源文件的开头包含头文件。在这方面,使用尖括号指定路径还是使用双引号无关。
从技术上讲,可以以强制将其他标头包含在标头之前的方式编写标头,但这通常是一种不好的代码味道,并且通常是一个错误。
一个例外是预编译头,它是某些编译器实现的非标准功能。预编译的标头必须位于源文件的任何声明(因此包括其他任何包含)之前。
嗯。我想我找到了问题。我在目录中有一个名为Utility.h.gch的二进制文件(不确定它来自哪里)。我删除了它,编译器问题就消失了。
啊。 gch是预编译标题使用的文件扩展名,这解释了为什么您的示例不足以重现您的问题。有关预编译头的行为的更多详细信息,请参见编译器的手册。
答案 1 :(得分:1)
“必须始终将括号中的标题始终列在首位”-否。
它与包含的顺序无关,并且与搜索包含的规则无关。
诸如#include "foo.h"
之类的include语句将使预处理程序首先在源文件的当前目录中查找,然后在提供的任何包含路径(以及默认路径)中查找 。像#include <foo.h>
这样的include语句将执行相同的操作,只是它将跳过初始的“在当前目录中查找”步骤。
答案 2 :(得分:1)
不。尖括号中包含的标题和引号中包含的标题之间的唯一区别是系统将在哪里查找它们。 (请注意,标准标头可能根本不会作为单独的文件存在;这是您无需担心的实现细节。)
答案 3 :(得分:0)
简短回答:否
长答案:
#include
指令几乎从字面上将该文件的内容粘贴到源文件中。必须先包含标题,然后才能使用其任何功能。期。如果您在末尾添加iostream
,但不使用该标头,则不会有问题