< 목표 > New Features in C99 (1) C99 의새로운기술을이해하기위한배경설명 ( 기존표준과의차이및도입배경 ) C99 에새로추가된기술일부에대한간략한소개 2003.10.11 KLDP 작은세미나전웅 (mycoboco@hanmail.net) < 구성 > <C 표준화의역사 > C 표준화의간략한역사 C99 표준화의원칙 (guideline) 새기술도입에대한항목을중심으로 각기술에대한소개 (21개 총 53개 ) 표준에의해명시된대표적기술중심 ( 명시되지않은기술도다수지만실제프로그래밍환경에주는영향없음 ) C90과깊은연관성갖는것을우선으로
< 표준화원칙 > ( 새기술도입에대한항목을중심으로 ) Existing code is important, existing implementations are not Avoid quiet changes Support international programming Codify existing practice to address evident deficiencies Minimize incompatibilities with C90 Minimize incompatibilities with C++ 1. Restricted character set support via digraph and <iso646.h> 표준 C 언어의기반 character set: ASCII가아닌 ISO 646 Invariant Set (ASCII 의 subset) C 언어는동시대다른언어에비해다양한그래픽문자사용 ASCII에는존재하지만 ISO 646 Invariant Set 에는존재하지않는 9개문자를위해 trigraph 도입 기존프로그램에대한영향을최소화하기위해?? 로시작하는 9개의 trigraph 정의토큰화이전에치환이이루어짐 1. Restricted character set support via digraph and <iso646.h> (Cont ) Trigraph 사용의예??=include <stdio.h> int main(void)??< printf("hello, world??-??/n"); printf( What??! ); 1. Restricted character set support via digraph and <iso646.h> (Cont ) trigraph 보다나은 6 개의 digraph 도입 trigraph 와는달리하나의독립된토큰으로사용됨 %:include <stdio.h> int main(void) %< printf("hello, world??-??/n");??> return 0; %> return 0;
1. Restricted character set support via digraph and <iso646.h> (Cont ) 프로그램의가독성증진을위한 <iso646.h> 매크로지원 trigraph 나 digraph 로쓰여져야하는연산자들을매크로로제공 and (&&) and_eq (&=) or ( ) compl (~) 2. More precise aliasing rule C 표준은모든종류의 aliasing 을허락하지는않음 void func(int *pi, unsigned int *pui) { *pui = 2; *pi = 3; another_func(*pui); /*? */ } int i; func(&i, (unsigned int *)&i); 2. More precise aliasing rule (Cont ) 2. More precise aliasing rule (Cont ) void func(int *pi, float *pf) { *pf = 2.0; *pi = 3; another_func(*pf); /*? */ } int i; func(&i, (float *)&i); /* wrong */ C90 의 aliasing rule 은 malloc() 로할당된 object 등과관련하여불완전한형태의규칙이었음 C99 에서는 effective type 이라는개념을도입하여 aliasing rule 과관련된문제의 거의 해결 union 과관련된문제로여전히개정중
3. Restricted pointer array object 의부분이 aliasing 되어 overlapped object 에대한 read/write 작업이있는경우, vector processing 같은최적화에치명적인영향을줌 void func(double *d, const double *s); array[] 3. Restricted pointer (Cont ) C90에서는이와같은행동을억제하는권고만을했을뿐 C99에서 restricted pointer의도입으로보다나은최적화가능 void func(double *restrict d, const double *restrict s); 동시에 overlapped object 를피해야하는함수들 (memcpy() 등 ) 의기술이용이해짐 s[] d[] 4. Flexible array member 5. Increased minimum translation limits struct foo { int number; double bar[100]; } *flexible; flexible = malloc( sizeof(struct foo) - sizeof(double)*100 + sizeof(double)*n); flexible->number = n; flexible->a[n-1] = 0; /* wrong */ struct foo { int number; double bar[1]; } *flexible; flexible = malloc( sizeof(struct foo) + sizeof(double)*(n-1)); flexible->number = n; flexible->a[n-1] = 0; /* wrong */ implementation 에게어느정도의물리적인자원을요구하기위한규정 : translation limits 일종의 guideline 의성격 ( 따라서, rubber teeth 라고불림 ) 컴퓨팅환경의발전에따라적절한수준으로확대되었음 C99 에서적법한방법 지원
6. Remove implicit int 7. return without expression typeless 언어 (BCPL, B) 에서발전해온 C 언어의특성으로과거언어의잔재가남아있음 main() /* int main() */ { return 0; } func(a, b) /* int a, b; */ { return a+b; } void foo(const i); /* const int i; */ implicit int 는 void 형이지원되지않던시절 void 의역할을대신하기도했음 proc() /* int proc() */ { /* do some jobs */ return; } C90 에서는 backward compatibility 를위해그대로유지 C99 에서는과감하게제거하였음 implicit int가사라졌으므로반환형이 void가아닌함수에서 return; 은더이상허락될필요없음 C99 에서금지그이전 (C99 이전 ) 에는알수없는반환값이사용되지않으면위와같은행동이허락되었음 8. Reliable integer division 9. Designated initializers C90 에서정수나눗셈연산의두피연산자중하나라도음수면, 결과의반올림방향은 implementation-defined 양의정수나눗셈의경우 round toward zero ( 소수부자름 ) 로반올림됨 int q = 7 / -3; /* -2 or -3 */ int r = 7 % -3; /* 1 or -2 */ 단, a % b == a ((a / b) * b) 를만족 C99 에서는음의정수나눗셈역시양의정수나눗셈과마찬가지로 round toward zero 로정의되었음 공용체초기화의문제 선언된첫번째멤버만을초기화할수있었음 union { int a; double b; } foo = { 12 }; 배열, 구조체초기화의문제 중간에존재하는멤버를초기화하기위해서는그앞의요소나멤버의초기치를모두명시해야함 C99에서는특정멤버나배열요소를지정해초기화할수있는방법제공 union { int a; double b; } foo = {.b = 3.14 }; int a[100] = { [52] = 7903 };
10. Relaxed constraints on aggregate and union initializers C90에서는 object의 storage duration이 static 이라도데이터형이 aggregate 혹은 union type 일경우, 초기치에는상수수식만이허락됨 C99에서는 scalar type의초기치와마찬가지로 auto storage duration의 aggregate 혹은 union type object의초기치에대한제한완화 void func(int n) { int array[10] = { n, n+1, n+2, }; /* wrong in C90, valid in C99 */ 11. // comment C++ 와의호환성증진을위해 // 형태의주석을받아들임기존의많은컴파일러가 C 프로그램에대해서도이미 // 주석을지원했으나이는표준을따르지않는확장 (non-conforming extension) // 주석의도입은드문경우지만 quiet change 에해당 int c_or_cpp = 10 //* wow */ 10 ; 12. Remove implicit function declaration 13. Mixed declaration and code 함수의 implicit declaration 제거 모든명칭은사용되기전에적절히선언되어야한다는현대프로그래밍언어의원칙 int main(void) int main(void) { { foo(some_value); extern int foo();... foo(some_value);... C90에서는 block 내에서선언이문장에우선해야함 C99에서는 block 내에서선언과문장이섞어나올수있음 { { double result, sum; double result, sum; /* logical unit #1 */ { /* logical #1 */ int first_result; int first_result; /* statements */ /* statements */ } /* logical unit #2 */ int second_result; { /* logical #2 */ /* statements */ int second_result;... /* statements */ }
14. Macro with a variable number of arguments C90 에서한매크로가받을수있는인자의개수는매개변수의개수에의해고정됨 #define debug(s, args) printf(s, args) debug_print( %d, %d\n, i, j); /* wrong */ 확장이아닌순수한 C90 에서가변인자매크로를흉내내기위한편법 #define debug(args) printf args debug(( %d, %d\n, i, j)); #define _, #define debug(s, args) printf(s, args) debug( %d, %d\n, i _ j); 14. Macro with a variable number of arguments (Cont ) C99 에서는 <stdarg.h> 방식과유사한가변인자매크로지원 #define debug(s,...) printf(s, VA_ARGS ) 이방법은일반함수의가변인자지원과유사하다는장점을갖지만, 기존 implementation 에서찾아보기어려운형태 사용중인 implementation 이 C99 방식을지원한다면미래를위해표준방식사용을권장 15. Empty macro argument 16. %lf allowed in printf 다수의 implemenation 이확장으로비어있는 (empty token) 매크로인자를지원하지만, C90 에서는엄격하게잘못된행동 #define make_obj(prefix, num) \ char *prefix ## num = #num decl_ptr(element, 13); /* char *prefix13 = 13 ; */ decl_ptr(element, ); /* wrong in C90 */ /* char *prefix = ; */ C99 에서는허락 C90 에서 printf() 에사용되는 format specifier 중에는 %lf 가존재하지않았음 그럼에도많은사용자들이 double 형의값을출력하기위해오해로사용하고, 이를위해다수의 implementation 이확장으로지원해왔음 double d = 3.14159; printf( %lf, d); /* wrong in C90 */ /* same as printf( %f\n, d); in C99 */ C99 에서는 %lf 를 double 을위한 specifier 로정식정의했음 ( 결국 %f 와동일 )
17. snprintf() family sprintf() 류의함수는 buffer overrun 과관련된위험성으로안전성을고려한프로그램에서는확장으로제공되는 snprintf() 류의함수를사용해왔음 snprintf() 함수는 C89 시절에제안되었으나 2/3 투표를얻지못해거절 C99 에서다수의 prior art 를확보하여받아들이게되었음 18. Idempotent type qualifiers C90 에서중복된 type qualifier 적용은잘못된것 const const int i; /* wrong in C90 */ typedef const int cint; const cint foo; /* wrong in C90 */ <signal.h> 의 sig_atomic_t 를위해중복된 type qualifier 적용을무해한것으로정의 typedef volatile int sig_atomic_t; volatile sig_atomic_t foo; /* okay in C99 */ 19. va_copy() macro 20. New struct type compatibility rule C90 은가변인자제어에사용되는 va_list 형의 object 를이식성있는방법으로복제할수있는방법제공하지않음 int foo(int n,...) { int i, sum; va_list ap, aq; va_start(ap, n); while ((i = va_arg(ap, int)) >= 0) sum += i; aq = ap; /* may not work */ for (i = 0; i < n; i++) sum += va_arg(ap, int); for (i = 0; i < n; i++) sum -= bar(va_arg(aq, int)); va_end(ap); } return sum; 두개의 translation unit ( 소스파일 ) 사이에서호환될수있는구조체, 공용체, 열거형의규칙에서 tag 은중요하지않았음 foo.c bar.c struct foo { struct bar { int a; int a; double b; double b; }; }; C99 에서는 tag 의동일성도요구
<New features in C99> restricted character set support via digraphs and <iso646.h> (AMD1) wide character library support in <wchar.h> and <wctype.h> (AMD1) more precise aliasing rules via effective type restricted pointers flexible array member variable- length arrays static and type qualifiers in parameter array declarators complex (and imaginary) support in <complex.h> type- generic math macros in <tgmath.h> the long long int type and library functions <New features in C99> (Cont ) increased minimum translation limits additional floating-point characteristics in <float.h> remove implicit int reliable integer division universal character names (\u and \U) extended identifiers hexadecimal floating-point constants and %a and %A printf/scanf conversion specifiers compound literals designated initializers // comments <New features in C99> (Cont ) <New features in C99> (Cont ) extended integer types and library functions in <inttypes.h> and <stdint.h> remove implicit function declaration preprocessor arithmetic done in intmax_t/uintmax_t mixed declarations and code new block scopes for selection and iteration statements integer constant type rules integer promotion rules macros with a variable number of arguments the vscanf family of functions in <stdio.h> and <wchar.h> additional math library functions in <math.h> floating-point environment access in <fenv.h> IEC 60559 (also known as IEC 559 or IEEE arithmetic) support trailing comma allowed in enum declaration %lf conversion specifier allowed in printf inline functions the snprintf family of functions in <stdio.h> boolean type in <stdbool.h> idempotent type qualifiers empty macro arguments new struct type compatibility rules (tag compatibility)
<New features in C99> (Cont ) additional predefined macro names _Pragma preprocessing operator standard pragmas func predefined identifier va_copy macro additional strftime conversion specifiers LIA compatibility annex deprecate ungetc at the beginning of a binary file remove deprecation of aliased array parameters conversion of array to pointer not limited to lvalues relaxed constraints on aggregate and union initialization relaxed restrictions on portable header names return without expression not permitted in function that returns a value (and vice versa) <C99 compilers> Comeau C/C++ compiler + Dinkumware library http://www.comeaucomputing.com http://www.dinkumware.com Intel C compiler (?) http://www.intel.com/software/products/compilers SGI C compiler (for IRIX) http://www.sgi.com/developers/devtools/languages/c.html gcc (partly) http://gcc.gnu.org lcc-win32 (partly) http://www.cs.virginia.edu/~lcc-win32