2016-12-16 2 views
0

Следующий код вызывает ошибку в компиляторе Green Hills C (ошибка: тип int * несовместим с типом аргумента const int *), тогда как он выдает предупреждение и компилируется с помощью gcc (предупреждение: передается аргумент 1 из «func» disards 'const' от целевого типа указателя).Может ли вызов функции отменить cons-определитель его параметра?

void func1(int* a) 
{ 
    (*a)++; 
} 

const int g = 100; 

void func2(void) 
{ 
    func1(&g); 
} 

Какое поведение соответствует стандарту C?

+0

Какое поведение вы ожидали? Вы изменяете значение, которое вы предоставляете компилятору, чтобы никогда не изменять его. – Olaf

+0

Это [интересный вопрос] (http://stackoverflow.com/questions/15576000/in-c-can-a-const-variable-be-modified-via-a-pointer)? –

ответ

1

Which behavior is according to C standard?

Оба поведения в компиляторах соответствуют стандарту. Поскольку @AnT уже объяснил, вызов func1(&g) нарушает языковое ограничение. Требование Стандарта на компилятор в таком случае выражается в пункте 5.1.1.3/1:

A conforming implementation shall produce at least one diagnostic message (identified in an implementation-defined manner) if a preprocessing translation unit or translation unit contains a violation of any syntax rule or constraint [...]

Как вы можете видеть, @Olaf правильно, что стандарт не различает разные категории диагностики. Это изобретение и con vention реализаций, которые обычно различают эти два на основе того, является ли ситуация фатальной для процесса компиляции. В стандарте нечего сказать о том, что компилятор должен делать, когда обнаружено нарушение ограничения, однако, ни вообще, ни в данном конкретном случае, поэтому он даже косвенно не указывает, должно ли быть «предупреждение» или «ошибка» излучается.

Если компилятор выполняет, он продолжает и в конечном итоге производит исполняемый файл, то вся полученная в результате программа обнаруживает неопределенное поведение, если в любой момент ее выполнения она вычисляет вызов проблемной функции. Это является причиной того, почему компилятор может не выбрасывать такой двоичный файл (например, может считаться, что нарушение ограничений является «ошибкой»), но, опять же, стандарт не предоставляет никаких указаний.

4

Неверный звонок в func1(&g). Это нарушение ограничений на языке C, то есть это то, что в повседневной терминологии обычно называют «ошибкой». Язык C не поддерживает неявное преобразование значения const int * в int *.

Тот факт, что это «просто предупреждение» в GCC, ничего не значит. Используйте переключатель -pedantic-errors в GCC, чтобы сделать его нарушениями ограничений отчетов как «ошибки». Компилятор Green Hills C, как вы заметили, сообщает об этом как «ошибку» без какой-либо помощи со своей стороны.

+0

Стандарт C не различает предупреждения и ошибки. Для определенных нарушений требуется только «диагностика». Он также не обеспечивает выполнение компилятором в случае нарушения. Все это вызывает UB. – Olaf

+0

@Olaf: Во-первых, стандарт C определяет понятие между * ограничением нарушения *. Термин «ошибка» часто [полу-] неофициально используется как синоним нарушения * ограничений *. Вот почему я взял его в кавычки, и именно так я использовал в своем ответе. Во-вторых, не каждое предупреждение, выданное компилятором, является признаком нарушения ограничений. – AnT

+0

В самом деле на самом деле большинство предупреждений являются ошибками - в том смысле, что они могут вызвать проблемы в некоторой реализации. То же самое и для кода OP: в средах, где хранятся «const» квалифицированные объекты в модифицируемой ОЗУ, проблем не будет. – Olaf

Смежные вопросы