Reputation: 97
I have written a straight forward program, but getting duplicate symbol linker error (error below) There is nothing additional in the .h file excepting for the @interface Fraction : NSObject @end
I am rather new to xcode.
//SAMPLE CODE
#import "JTViewController.h"
@interface Fraction ()
-(void) print;
-(void) setNumerator: (int) n;
-(void) setDenominator: (int) d;
@end
@implementation Fraction
{
int numerator;
int denominator;
}
-(void) print
{
NSLog (@"%i/%i", numerator, denominator);
}
-(void) setNumerator:(int)n
{
numerator = n;
}
-(void) setDenominator:(int)d
{
denominator = d;
}
@end
int main (int argc, char * argv[])
{
@autoreleasepool {
// Create an instance of Fraction and initialise it
Fraction *myFraction = [[Fraction alloc] init];
//Set Fraction to 1/3
[myFraction setNumerator: 1];
[myFraction setDenominator: 3];
//Display the fraction using the print method
[myFraction print];
}
return 0;
}
This is the error
Ld /Users/jamesmurray/Library/Developer/Xcode/DerivedData/BrandNew-akqlirretjwoeuaqkrwlbqmlqxlc/Build/Products/Debug-iphonesimulator/BrandNew.app/BrandNew normal i386
cd /Users/jamesmurray/AppsDev/BrandNew
setenv IPHONEOS_DEPLOYMENT_TARGET 6.1
setenv PATH "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin:/Applications/Xcode.app/Contents/Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin"
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -arch i386 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator6.1.sdk -L/Users/jamesmurray/Library/Developer/Xcode/DerivedData/BrandNew-akqlirretjwoeuaqkrwlbqmlqxlc/Build/Products/Debug-iphonesimulator -F/Users/jamesmurray/Library/Developer/Xcode/DerivedData/BrandNew-akqlirretjwoeuaqkrwlbqmlqxlc/Build/Products/Debug-iphonesimulator -filelist /Users/jamesmurray/Library/Developer/Xcode/DerivedData/BrandNew-akqlirretjwoeuaqkrwlbqmlqxlc/Build/Intermediates/BrandNew.build/Debug-iphonesimulator/BrandNew.build/Objects-normal/i386/BrandNew.LinkFileList -Xlinker -objc_abi_version -Xlinker 2 -fobjc-arc -fobjc-link-runtime -Xlinker -no_implicit_dylibs -mios-simulator-version-min=6.1 -framework UIKit -framework Foundation -framework CoreGraphics -o /Users/jamesmurray/Library/Developer/Xcode/DerivedData/BrandNew-akqlirretjwoeuaqkrwlbqmlqxlc/Build/Products/Debug-iphonesimulator/BrandNew.app/BrandNew
duplicate symbol _main in:
/Users/jamesmurray/Library/Developer/Xcode/DerivedData/BrandNew-akqlirretjwoeuaqkrwlbqmlqxlc/Build/Intermediates/BrandNew.build/Debug-iphonesimulator/BrandNew.build/Objects-normal/i386/main.o
/Users/jamesmurray/Library/Developer/Xcode/DerivedData/BrandNew-akqlirretjwoeuaqkrwlbqmlqxlc/Build/Intermediates/BrandNew.build/Debug-iphonesimulator/BrandNew.build/Objects-normal/i386/JTViewController.o
ld: 1 duplicate symbol for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I have no idea where it came from. Any assistance would be appreciated.
Upvotes: 0
Views: 466
Reputation: 74355
There is nothing special about main
here. You can only have one globally visible non-common symbol in your object files. Non-static functions are globally visible and non-common symbols, hence you can only have a function with a specific name defined only once. For example:
a.c
:
int func() { ... }
b.c
:
void func(int arg) { ... }
When both files are compiled, it creates two globally visible symbols with the name of func
(with whatever decoration the compiler might apply to the symbol), despite the difference in the argument lists and the return types. As the linker tries to resolve all symbol references in order to produce the final executable, it faces the hard choice of selecting the right version of func
, so it takes the most direct approach - simply gives you an error about duplicate symbol definition and bails out.
This is not a requirement unique to the C language (and Objective-C is basically a runtime extension of C) as it is imposed by the system linker. It also translates to many other languages like Objective-C, C++, Fortran, Pascal, etc. In C++ function symbols are decorated according to the namespace they live in and the list of their arguments (the former enables function overloading), but again one cannot have two functions with the same list of arguments in the same namespace defined in different source files.
Usually C and C++ functions are compiled to globally visible symbols unless the static
modifier is applied:
a.c
:
static int func() { ... }
b.c
:
void func(int arg) { ... }
This would not result in a global symbol func
in a.o
clashing with the one in b.o
and the linker would not complain. It would also work if rather func
in b.c
is given the static
treatment or if both functions are static
.
Upvotes: 0
Reputation: 122381
Like the linker error says, you have two main()
functions; one in main.m
and one in JTViewController.m
.
Remove the one in JTViewController.m
(move the functionality into main.m
).
Upvotes: 2