1

I am tring to create a private 2D float array and initialize it in constructor. I am getting "Expected Expression" error. I searched for a long while and couldn't find anything.

Here is my code:

@interface SampleClass : NSObject{
@private
    float stops[2][2];
}

@end

@implementation SampleClass

- (id) init{
    self = [super init]; // Edited
    stops = { {1.0, 1.0}, {1.0, 2.0} }; // It gives "Expected Expression" at this line
    return self;
}

@end

I tried different versions like:

stops = { {1.0, 1.0}, {1.0, 2.0} };
stops = { 1.0, 1.0, 1.0, 2.0 };
stops[][] = { {1.0, 1.0}, {1.0, 2.0} };

Non of them seems to work.

I am new to Objective C so any recommendation is appreciated.

M. Azyoksul
  • 1,580
  • 2
  • 16
  • 43
  • 1
    Not related to the issue but you must call `super` in `init`. Take a look at [init](https://developer.apple.com/documentation/objectivec/nsobject/1418641-init). – Willeke Jul 02 '18 at 10:38

1 Answers1

1

(Objective-)C does not support assignment of one array to another, there are workarounds involving struct as they are assignable but you don't need to go there.

If you are after a constant array to be used by instances you can just declare it as static:

static const float stops[2][2] = { {27.3, 51.7}, {93.2, 42.24}};

The static makes stops accessible only to code within the same file. You can place the declaration between the @implementation and @end to at least visually associate it as belonging to a class.

The above is not suitable if you need a variable array, but does form part of a solution. Keep your instance variable:

@private
   float stops[2][2];

This must be an array, not some pointer, as it must allocate the space for your floats. Next use the above declaration but give it a different name:

static const float _stops_init[2][2] = { {27.3, 51.7}, {93.2, 42.24}};

and then in your init use the standard C function memcpy() to copy the values in the memory occupied by _stops_init into the memory occupied by stops:

memcpy(stops, _stops_init, sizeof(_stops_init));

Here sizeof() will return the total size in bytes of the memory used by your float array _stops_init and memcpy() copies those bytes over those associated with stops – that is it implements array assignment which C doesn't directly support.

Using the static const array rather than a local variable define in init() as the source of your values saves re-creating the source on every call to init().

The above code doesn't do all the checks it should - at minimum an assert() checking that the sizes of stops and _stops_init are the same is advisable.

HTH

CRD
  • 52,522
  • 5
  • 70
  • 86
  • Should I put the static _stops_init array decleration inside curly brackets right after @implementarion or just directly inside it, next to class methods? What is the difference? – M. Azyoksul Jul 03 '18 at 05:43
  • The declaration goes at file level, just like methods. Technically you are declaring a variable with the lifetime of a global but whose name visibility is scoped to the file. Braces directly following `@implementation` enclose instance variable declarations. Indeed it is better if you drop the `@private` and move the declaration of `stops` into this implementation instance variable declaration area, such variables are automatically only accessible from within the implementation which is good practice for instance variables. – CRD Jul 03 '18 at 06:06