2017-10-15 16 views
0

は、4つのファイルのセットを提供します:エラーC2156:プラグマが関数外にある必要があります - この場合、どうしてですか?

file1.h:

#pragma once 
#include <windows.h> 

file1.cpp:

#include "file1.h" 

file2.h:

#pragma once 

#define N 666 

file2.cpp:

#include "file2.h" 
#include "file1.h" 

私はエラーの束を買ってあげるのVisual Studio 2015のコンパイラcl -c file2.cppとfile2.cppをコンパイルしよう:

Microsoft (R) C/C++ Optimizing Compiler Version 19.00.24215.1 for x86 
Copyright (C) Microsoft Corporation. All rights reserved. 

file2.cpp 
C:\Program Files (x86)\Windows Kits\8.1\include\\um\winnt.h(1179): error C2059: syntax error: 'constant' 
C:\Program Files (x86)\Windows Kits\8.1\include\\um\winnt.h(2149): error C2598: linkage specification must be at global scope 
C:\Program Files (x86)\Windows Kits\8.1\include\\um\winnt.h(4807): error C2598: linkage specification must be at global scope 
C:\Program Files (x86)\Windows Kits\8.1\include\\um\winnt.h(4859): error C2156: pragma must be outside function 
C:\Program Files (x86)\Windows Kits\8.1\include\\um\winnt.h(4991): error C2598: linkage specification must be at global scope 
C:\Program Files (x86)\Windows Kits\8.1\include\\um\winnt.h(5050): error C2156: pragma must be outside function 
C:\Program Files (x86)\Windows Kits\8.1\include\\um\winnt.h(5051): error C2156: pragma must be outside function 
C:\Program Files (x86)\Windows Kits\8.1\include\\um\winnt.h(5052): error C2156: pragma must be outside function 
C:\Program Files (x86)\Windows Kits\8.1\include\\um\winnt.h(5053): error C2156: pragma must be outside function 
C:\Program Files (x86)\Windows Kits\8.1\include\\um\winnt.h(5054): error C2156: pragma must be outside function 
C:\Program Files (x86)\Windows Kits\8.1\include\\um\winnt.h(5055): error C2156: pragma must be outside function 
C:\Program Files (x86)\Windows Kits\8.1\include\\um\winnt.h(5078): error C2156: pragma must be outside function 
C:\Program Files (x86)\Windows Kits\8.1\include\\um\winnt.h(5079): error C2156: pragma must be outside function 
C:\Program Files (x86)\Windows Kits\8.1\include\\um\winnt.h(5134): error C2156: pragma must be outside function 
C:\Program Files (x86)\Windows Kits\8.1\include\\um\winnt.h(5135): error C2156: pragma must be outside function 
C:\Program Files (x86)\Windows Kits\8.1\include\\um\winnt.h(5136): error C2156: pragma must be outside function 
C:\Program Files (x86)\Windows Kits\8.1\include\\um\winnt.h(5137): error C2156: pragma must be outside function 
C:\Program Files (x86)\Windows Kits\8.1\include\\um\winnt.h(15420): error C2059: syntax error: 'constant' 
C:\Program Files (x86)\Windows Kits\8.1\include\\um\winnt.h(15420): error C2238: unexpected token(s) preceding ';' 
C:\Program Files (x86)\Windows Kits\8.1\include\\um\winnt.h(15439): error C2059: syntax error: 'constant' 
C:\Program Files (x86)\Windows Kits\8.1\include\\um\winnt.h(15439): error C2238: unexpected token(s) preceding ';' 

しかし、私は、ファイルを[OK]をコンパイルされます#define N 666行をコメントます。誰が私にここで起こっていることを説明できますか?私がそれを得ないので、docsは私に何も解決していません。

+3

理解[何マクロは実際には(http://en.cppreference.com/w/cpp/preprocessor/replace)行い、「N」は一般的に使用される識別子であると考えます。 – chris

+0

マクロ定義で 'um/winnt.h'ヘッダに何かがありますが、それは明らかに' windows.h'に含まれていると思います。その場合、file2.cppの '#include'ディレクティブの順序を反転することで問題を解決する必要があります。 –

+0

'const int'でマクロを使う理由は何ですか?なぜグローバルなのでしょうか?そしてなぜそれが「N」よりも優れていて、説明的な名前を持っていないのですか? –

答えて

2

Nは、winnt.hを含むwindows.hと衝突します。例えば

extern "C++" // templates cannot be declared to have 'C' linkage 
template <typename T, size_t N> 
char (*RtlpNumberOf(UNALIGNED T (&)[N]))[N]; 

私はいつでもあなたができるマクロを使用しないようにお勧めします。 CおよびC++の両方で、あなたはconstオブジェクトでマクロ定義を置き換えることを検討できます。

const int N = 666; 

constのデフォルトの結合が外部にあるので、Cには、あなたが、static constをそう使う可能性があることに注意)

+0

ありがとう、私はそのマクロが 'windows.h'ファイルに表示されるのを知らなかった – BPL

1

"N"のような短い名前のマクロは定義しないでください。ほぼ100%の確率で、これはWindows.hのように後でインクルードするヘッダー内のものと衝突します。その中のどこかに "N"が記述されていると、プリプロセッサはプログラムを666に置き換えます。デバッグするのが難しい他の奇妙なプリプロセッサ効果や、あなた自身を含むヘッダーファイルのユーザーにとっての悪夢を引き起こします。とにかく

、あなたは(特にヘッダファイルには、あなたが本当にすべきでない)それを行う上で主張すれば、あなたは任意のヘッダを含めた後、Nを#defineしていることを確認します

に解決されます

#include "file1.h" 
#include "file2.h" 

#include <windows.h> 
#define N666 

プリプロセッサの仕組みによって、翻訳単位ごとに含める順序が重要です。

関連する問題