Определение статического члена в target-C и Objective-C++

У меня есть разница при компиляции source-c и source-C++.

Вот объявление Class1 и Class2 в test.h:

#import <Foundation/Foundation.h>

@interface Class1 {
}
@end

@interface Class2 {
}
@end

Теперь это реализация Objective-C в test.m:

#import "test.h"

@implementation Class1
/* static member */
static int mystatic;
@end


@implementation Class2
/* static member */
static int mystatic;
@end

Я успешно компилирую с этой командой:

gcc -arch armv6 -isysroot /Developer/.../iPhoneOS5.0.sdk -x objective-c -c test.m

Теперь я использую именно эту реализацию Objective-C++ test.mm (точно такой же источник):

#import "test.h"

@implementation Class1
/* static member */
static int mystatic;
@end


@implementation Class2
/* static member */
static int mystatic;
@end

И скомпилируйте с этой командной строкой (разница в опции -x):

gcc -arch armv6 -isysroot /Developer/.../iPhoneOS5.0.sdk -x objective-c++ -c test.mm

Но я получаю ошибку:

test.mm:11 error: redefinition if 'int mystatic'

Почему я получаю эту ошибку в ObjC++, а не в ObjC?

1 ответ

Решение

Это сводится к разнице между C и C++. В C все в порядке, чтобы переопределить статическую переменную с тем же именем и тем же типом; в C++ делать то же самое - ошибка.

Из стандарта С:

Объявление идентификатора для объекта, который имеет область файла без инициализатора и без спецификатора класса хранения или со статическим спецификатором класса хранения, составляет предварительное определение. Если модуль перевода содержит одно или несколько предварительных определений для идентификатора, а модуль перевода не содержит внешних определений для этого идентификатора, то поведение точно такое, как если бы модуль перевода содержал объявление области файла для этого идентификатора с составным типом как конца блока перевода, с инициализатором, равным 0.

Из стандарта C++:

C.1.2, 3.1 Изменение: C++ не имеет "предварительных определений", как в C. Например, на уровне файла,

int i ;
int i ;

допустим в C, [но он] недействителен в C++.

Что касается Цели C, язык не поддерживает переменные, ограниченные областью действия на уровне класса; декларирование static int mystatic; внутри @implementation блок имеет точно такой же эффект, как и объявление его вне @implementation блок. Чтобы эмулировать переменные в области классов, используйте статические переменные в области функций внутри методов класса.

Другие вопросы по тегам