2013-09-21 73 views
5

我正在嘗試在Xcode 4.6.3中構建一個C++項目。xcode中的隨機重複符號(C++)

在我的項目(一個非常簡單的OpenGL遊戲的開始),我有兩個文件:

textures.h:

#pragma once 

#include <GLUT/GLUT.h> 

void load(); // load textures 

GLuint dirt, water; // variables to store texture handles 

textures.cpp:

#include "textures.h" 

#include "util.h" 

void textures::load() { 
    dirt = util::loadTexture("/Some/Path/Soil.png"); 
    water = util::loadTexture("/Some/Path/Water_fresh.png"); 
} 

這裏util.h定義了util :: loadTexture函數。

有兩個文件包含textures.h。第一個(main.cpp)調用load()函數作爲初始化的一部分,並訪問dirt變量來綁定Soil.png紋理。第二個(Chunk.cpp)包含textures.h,但實際上並沒有訪問任何東西。

當我嘗試生成項目,它給了我下面的錯誤:

duplicate symbol _dirt in: 
    /Users/me/Library/Developer/Xcode/DerivedData/OpenGL_Testing-epporrdukapbwzawfhiwnlztzdns/Build/Intermediates/OpenGL Testing.build/Debug/OpenGL Testing.build/Objects-normal/x86_64/main.o 
    /Users/me/Library/Developer/Xcode/DerivedData/OpenGL_Testing-epporrdukapbwzawfhiwnlztzdns/Build/Intermediates/OpenGL Testing.build/Debug/OpenGL Testing.build/Objects-normal/x86_64/Chunk.o 
duplicate symbol _water in: 
    /Users/me/Library/Developer/Xcode/DerivedData/OpenGL_Testing-epporrdukapbwzawfhiwnlztzdns/Build/Intermediates/OpenGL Testing.build/Debug/OpenGL Testing.build/Objects-normal/x86_64/main.o 
    /Users/me/Library/Developer/Xcode/DerivedData/OpenGL_Testing-epporrdukapbwzawfhiwnlztzdns/Build/Intermediates/OpenGL Testing.build/Debug/OpenGL Testing.build/Objects-normal/x86_64/Chunk.o 
duplicate symbol _dirt in: 
    /Users/me/Library/Developer/Xcode/DerivedData/OpenGL_Testing-epporrdukapbwzawfhiwnlztzdns/Build/Intermediates/OpenGL Testing.build/Debug/OpenGL Testing.build/Objects-normal/x86_64/main.o 
    /Users/me/Library/Developer/Xcode/DerivedData/OpenGL_Testing-epporrdukapbwzawfhiwnlztzdns/Build/Intermediates/OpenGL Testing.build/Debug/OpenGL Testing.build/Objects-normal/x86_64/textures.o 
duplicate symbol _water in: 
    /Users/me/Library/Developer/Xcode/DerivedData/OpenGL_Testing-epporrdukapbwzawfhiwnlztzdns/Build/Intermediates/OpenGL Testing.build/Debug/OpenGL Testing.build/Objects-normal/x86_64/main.o 
    /Users/me/Library/Developer/Xcode/DerivedData/OpenGL_Testing-epporrdukapbwzawfhiwnlztzdns/Build/Intermediates/OpenGL Testing.build/Debug/OpenGL Testing.build/Objects-normal/x86_64/textures.o 
ld: 4 duplicate symbols for architecture x86_64 
clang: error: linker command failed with exit code 1 (use -v to see invocation) 

我明白,這意味着有重複的地方,或頭被包含多次。但是我的所有頭文件都使用了#pragma once,並且我在工作區中搜索了「髒物」等,並且沒有其他定義。我的其他頭文件工作正常,甚至包含多次包含的頭文件。我用不同的關鍵字多次搜索了這個問題,並且看過其他類似的問題,但是我發現的全部是this SO question

我在Xcode之前遇到過其他「隨機」錯誤 - 例如,一個項目不斷嘗試使用我已刪除的動態庫,並用靜態庫替換。即使我創建了一個全新的項目,錯誤仍然存​​在。它從終端手動編譯時工作。

我錯過了什麼?

回答

5

#pragma once不停止多次包含頭文件。

當編譯單個文件時,它停止多次包含頭文件。你有(至少)三個文件,所以你要聲明3次相同的變量。

不要將變量定義放在頭文件中。做到這一點,而不是

// textures.h 
extern GLuint dirt, water; // variable declarations 


// textures.cpp 
GLuint dirt, water; // variable definitions 

,只要你想(只要它們都是相同的),你可以有一個可變的許多聲明,所以沒關係把聲明在頭文件中,必須有且只有一個變量定義,所以你把它放在一個.cpp文件中。

要記住的關鍵是每個.cpp文件都完全獨立於其他.cpp文件編譯,這被稱爲單獨編譯。所以你的想法,即#pragma once將阻止頭文件被包含在一個.cpp文件中,只是因爲它已經被包含在另一個.cpp文件中,這是行不通的。你不是第一個誤解這個。

+0

我已經嘗試用#pragma替換Xcode最初創建的#ifndef #define #endif,但它仍然無效... – qxz

+0

嗯#ifndef ...與#pragma一模一樣,並且沒有做出您認爲應該出於同樣原因進行的操作。我發佈的內容不是提示,而是使用全局變量的正確方法。 – john

+0

不要停止使用#pragma once或#ifndef ...它只是解決了您認爲它所做的一個不同的問題。 – john