0

I'm trying to use @property and @sythesize correctly, but run into these errors. Does anyone know what's wrong with this code? This looks like how it should be used, but is not compiling correctly.

Thanks!

#import <Foundation/Foundation.h>

@interface A: NSObject

@property int a;

@end

@implementation A
int a;

@synthesize a;

@end

int main (int argc, char * argv[])
{
  @autoreleasepool {
    A *a = [[A alloc] init];

    [a setA:99];
    int v = [a getA];
    NSLog (@" %d\n", v);
  }
  return 0;
}

clang-7 -o a.out otest1.m -I `gnustep-config --variable=GNUSTEP_SYSTEM_HEADERS` -L `gnustep-config --variable=GNUSTEP_SYSTEM_LIBRARIES` -lgnustep-base -fconstant-string-class=NSConstantString -D_NATIVE_OBJC_EXCEPTIONS -lobjc && ./a.out
otest1.m:12:13: error: synthesized property 'a' must either be named the same as a
      compatible instance variable or must explicitly name an instance variable
@synthesize a;
            ^
otest1.m:22:16: warning: instance method '-getA' not found (return type defaults to 'id')
      [-Wobjc-method-access]
    int v = [a getA];
               ^~~~
otest1.m:3:12: note: receiver is instance of class declared here
@interface A: NSObject
           ^
otest1.m:22:9: warning: incompatible pointer to integer conversion initializing 'int' with
      an expression of type 'id' [-Wint-conversion]
    int v = [a getA];
        ^   ~~~~~~~~
2 warnings and 1 error generated.
411 [debian:~/src/c]$ 

UPDATE: The solution is that @synthesize creates method setA and a. Not setA and getA. I'm confused by this but it appears to be the problem in compilation. I tested the solution here using clang on Mac OS Catalina and clang on Linux and it works.

notaorb
  • 1,944
  • 1
  • 8
  • 18
  • Do these help? https://stackoverflow.com/questions/10476385/synthesized-properties-and-ivar-error/24337237#24337237 https://stackoverflow.com/questions/7110245/error-building-32-bit-os-x-app – jtbandes May 23 '20 at 22:09
  • @jtbandes per recommendations in that post I declared "int pa" in the implementation section and the error still persists. – notaorb May 23 '20 at 22:16
  • Perhaps try `_pa`? Or `@synthesize pa=pa;`? BTW, your main function is wrong, you probably meant `[a setPa:99]` rather than `[A setPa:99]`. – jtbandes May 23 '20 at 22:17
  • @jtbandes updated code, same error. Were you thinking it's a namespace conflict re: _pa? – notaorb May 23 '20 at 22:28
  • @Willeke I'm unable to put { int a; } under implementation with braces. I have to place it under implementation without braces for things to compile. – notaorb May 24 '20 at 01:04

1 Answers1

0

The correct syntax to define an instance variable named a is:

@implementation A
    {
        int a;
    }

    @synthesize a;

@end

Yet only recent language versions of Objective-C support instance variables in the implementation and only when building for 64 bit. Older versions and 32 bit only support instance variable in the interface:

@interface A: NSObject
    { 
        @private
        int a;
    }

    @property int a;

@end

Very new versions of Objective-C even auto-synthesize properties and work best if you don't use @synthesize at all in the implementation.

Mecki
  • 125,244
  • 33
  • 244
  • 253
  • Tried that, it gives error: inconsistent number of instance variables specified int a; ^ – notaorb May 24 '20 at 01:02
  • 1
    @notaorb In that case your Obj-C implementation uses an even older syntax than I expected. Originally everything was defined in the interface, later on the language was modified to support to put most stuff into the implementation and meanwhile all of this is automated by the compiler in even later versions. – Mecki May 24 '20 at 11:16
  • I'm using clang on Linux. Hopefully someone can chime in that can compile this correctly on Linux. – notaorb May 24 '20 at 17:31