Рубрики

Стандарт языка программирования C

Идея этой статьи состоит в том, чтобы ввести стандарт Си.

Что делать, если программа на Си дает разные результаты в двух разных компиляторах?
Например, рассмотрим следующую простую программу на Си.

void main() {  }

Вышеприведенная программа завершается ошибкой в gcc, так как возвращаемый тип main не имеет значения, но она компилируется в Turbo C. Как мы решаем, является ли она допустимой программой на C или нет?

Рассмотрим следующую программу в качестве другого примера. Он дает разные результаты в разных компиляторах.

#include<stdio.h>

int main()

{

    int i = 1;

    printf("%d %d %d\n", i++, i++, i);

    return 0;

}

2 1 3 - using g++ 4.2.1 on Linux.i686
1 2 3 - using SunStudio C++ 5.9 on Linux.i686
2 1 3 - using g++ 4.2.1 on SunOS.x86pc
1 2 3 - using SunStudio C++ 5.9 on SunOS.x86pc
1 2 3 - using g++ 4.2.1 on SunOS.sun4u
1 2 3 - using SunStudio C++ 5.9 on SunOS.sun4u

Источник: Stackoverflow

Какой компилятор прав?

Ответ на все такие вопросы — стандарт Си. Во всех таких случаях нам нужно увидеть, что стандарт C говорит о таких программах.

Что такое стандарт С?
Последним стандартом C является ISO / IEC 9899: 2011 , также известный как C11, так как окончательный вариант был опубликован в 2011 году. До C11 был C99 . Окончательный вариант C11 доступен здесь . Смотрите это для полной истории стандартов C.

Можем ли мы знать поведение всех программ из стандарта C?
Стандарт C оставляет некоторое поведение многих конструкций C неопределенным, а некоторые неопределенным, чтобы упростить спецификацию и обеспечить некоторую гибкость в реализации. Например, в C использование любой автоматической переменной до ее инициализации приводит к неопределенному поведению, а порядок вычислений подвыражений не определен. Это, в частности, позволяет компилятору делать все, что проще и эффективнее, если такая программа будет представлена.

Итак, каков вывод о двух приведенных выше примерах?
Давайте рассмотрим первый пример, который называется «void main () {}», стандарт говорит следующее о прототипе main ().

The function called at program startup is named main. The implementation 
declares no prototype for this function. It shall be defined with a return 
type of int and with no parameters:
       int main(void) { /* ... */ }
or with two parameters (referred to here as argc and argv, though any names 
may be used, as they are local to the function in which they are declared):
       int main(int argc, char *argv[]) { /* ... */ }
or equivalent;10) or in some other implementation-defined manner.

Таким образом, возвращаемый тип void не соответствует стандарту, и это разрешено некоторыми компиляторами.

Давайте поговорим о втором примере. Обратите внимание, что следующее утверждение в стандарте C приведено в разделе неопределенного поведения.

The order in which the function designator, arguments, and 
subexpressions within the arguments are evaluated in a function 
call (6.5.2.2). 

Что делать с программами, поведение которых не определено или не указано в стандарте?
Как программист, никогда не стоит использовать программные конструкции, поведение которых не определено или не определено, такие программы всегда следует поощрять. Вывод таких программ может меняться в зависимости от компилятора и / или компьютера.

Эта статья предоставлена Абхай Рати . Пожалуйста, пишите комментарии, если вы обнаружите что-то неправильное или вы хотите поделиться дополнительной информацией по обсуждаемой выше теме.

Рекомендуемые посты:

Стандарт языка программирования C

0.00 (0%) 0 votes