54

I declared a constant in a header file const double EARTH_RADIUS=6353; that is imported to various other headers and I got a linker error.

Ld /Users/Teguh/Library/Developer/Xcode/DerivedData/BadgerNew-bjopcgcgsjkcvcevflfbvsjwfgnu/Build/Products/Debug-iphonesimulator/BadgerNew.app/BadgerNew normal i386
    cd /Users/Teguh/Dropbox/badgers/BadgerNew
    setenv MACOSX_DEPLOYMENT_TARGET 10.6
    setenv PATH "/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin:/Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin"
    /Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/llvm-g++-4.2 -arch i386 -isysroot /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.3.sdk -L/Users/Teguh/Library/Developer/Xcode/DerivedData/BadgerNew-bjopcgcgsjkcvcevflfbvsjwfgnu/Build/Products/Debug-iphonesimulator -F/Users/Teguh/Library/Developer/Xcode/DerivedData/BadgerNew-bjopcgcgsjkcvcevflfbvsjwfgnu/Build/Products/Debug-iphonesimulator -filelist /Users/Teguh/Library/Developer/Xcode/DerivedData/BadgerNew-bjopcgcgsjkcvcevflfbvsjwfgnu/Build/Intermediates/BadgerNew.build/Debug-iphonesimulator/BadgerNew.build/Objects-normal/i386/BadgerNew.LinkFileList -mmacosx-version-min=10.6 -Xlinker -objc_abi_version -Xlinker 2 -framework CoreLocation -framework UIKit -framework Foundation -framework CoreGraphics -framework CoreData -o /Users/Teguh/Library/Developer/Xcode/DerivedData/BadgerNew-bjopcgcgsjkcvcevflfbvsjwfgnu/Build/Products/Debug-iphonesimulator/BadgerNew.app/BadgerNew

ld: duplicate symbol _EARTH_RADIUS in /Users/Teguh/Library/Developer/Xcode/DerivedData/BadgerNew-bjopcgcgsjkcvcevflfbvsjwfgnu/Build/Intermediates/BadgerNew.build/Debug-iphonesimulator/BadgerNew.build/Objects-normal/i386/NearbyIsiKota.o and /Users/Teguh/Library/Developer/Xcode/DerivedData/BadgerNew-bjopcgcgsjkcvcevflfbvsjwfgnu/Build/Intermediates/BadgerNew.build/Debug-iphonesimulator/BadgerNew.build/Objects-normal/i386/FrontPageofBadger.o for architecture i386
collect2: ld returned 1 exit status

Basically I want the constant to be available for all classes on my project. Where should I declare it?

Cœur
  • 37,241
  • 25
  • 195
  • 267
user4951
  • 32,206
  • 53
  • 172
  • 282

4 Answers4

96

You can declare in the header, define it in a code file. Simply declare it as

extern const double EARTH_RADIUS;

then in a .m file somewhere (usually the .m for the .h you declared it in)

const double EARTH_RADIUS = 6353;
Dan F
  • 17,654
  • 5
  • 72
  • 110
  • Do you actually need to do the extern in the header ? Without it, it seems to work. – Paweł Brewczynski Jan 06 '15 at 22:13
  • 8
    `extern` in the header allows other files to know about your constant. If you only need the constant for the scope of a single file, then the `extern` is not necessary. – Dan F Jan 07 '15 at 12:20
  • in .m, does it matter if before or after `@implementation`? – kraftydevil May 27 '15 at 16:18
  • 4
    @kraftydevil technically it doesn't matter, but the convention is to do it after your `#import`s and before the `@implementation`. But really anywhere in the global scope of the file is fine (meaning as long as it isn't inside any curly braces `{}` – Dan F May 28 '15 at 10:50
65

There are two ways to accomplish this:

1st option- As previous replies pointed, in the .h file:

myfile.h
extern const int MY_CONSTANT_VARIABLE;

and in myfile.m define them

myfile.m    
const int MY_CONSTANT_VARIABLE = 5;

2nd option- My favourite:

myfile.h
static const int MY_CONSTANT_VARIABLE = 5 ;
spacebiker
  • 3,777
  • 4
  • 30
  • 49
4

Declare it in a source file and have external linkage to it( using extern keyword ) so as to use in all other source files.

Mahesh
  • 34,573
  • 20
  • 89
  • 115
1

Best practice would be to declare it in your .h and .m files. See Constants in Objective-C for a very detailed set of answers regarding this same question.

Community
  • 1
  • 1
Kyle Clegg
  • 38,547
  • 26
  • 130
  • 141