비원형 함수의 선언은 가변인자를 가지는 함수와는 호환될 수 없다.

아래는 비원형 선언엔 대한 포인터를 통해 가변인자를 가지는 함수를 호출하려 할때  정의되지 않은 행동(undefined behavior)을 보여주는 예이다.



#include <stdio.h>
#include <stdarg.h>

typedef void (callptr)();

static void fixed(void *something, double val)
{
    printf("%f\n", val);
}

static void dynamic(void *something, ...)
{
    va_list args;
    va_start(args, something);
    double arg = va_arg(args, double);
    printf("%f\n", arg);
}

int main()
{
    double x = 1337.1337;
    callptr *dynamic_func = (callptr *) &dynamic;
    dynamic_func(NULL, x);
    callptr *fixed_func = (callptr *) &fixed;
    fixed_func(NULL, x);

    printf("%f\n", x);
}




$ gcc -m32 -o test test.c
$ file test
test: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.9, not stripped
$ ./test
1337.133700
1337.133700
1337.133700

$ gcc -o test test.c
$ file test
test: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.9, not stripped
$ ./test
1337.133700
1337.133700
1337.133700

C:\>gcc -o test.exe test.c
C:\>file test.exe
test.exe: PE32 executable for MS Windows (console) Intel 80386 32-bit
C:\>test.exe
1337.133700
1337.133700
1337.133700

C:\>x86_64-w64-mingw32-gcc -o test.exe test.c
C:\>file test.exe
test.exe: PE32+ executable for MS Windows (console) Mono/.Net assembly
C:\>test.exe
0.000000
1337.133700
1337.133700




대부분의 임플리멘테이션에서는 프로그래머가 의도한 결과를 보여준다. 하지만 Win64에서는 0을 출력한다.


함수 포인터(pointer to function)은 내부표현이나 정렬제한(alignment requirement)문제를 가지지 않기때문에 호환되지 않는 함수의 포인터를 가질 수 있지만, 호출을 할때는 호환되는 함수형을 가지고 있어야 한다. 만약 그렇지 않다면 정의되지 않은 행동(undefined behavior)이며, 이는 위와 같이 임플리멘테이션(implementation)에 따라 결과가 달라질 수 있다.


((void (*)(void *, ...))dynamic_func)(NULL, x);

따라서 위와 같이 호환되는 함수형으로 호출하여야 한다.



( http://stackoverflow.com/questions/7308449/how-to-use-varargs-in-conjunction-with-function-pointers-in-c-on-win64 )

Posted by shany0_0
,

Head First C

Study/책 2015. 1. 4. 22:34

 

 

 

대부분의 국내에 출판된 C언어 입문 서적이 윈도우 환경에서의 개발을 가정하고 있다. 덕분에 대부분의 C언어 강의도 윈도우 환경에서 진행되고 있다. 하지만 윈도우에서의 C는 진짜 C의 모습을 알기가 어려운 점이 많다.

이 책은 linux환경에서의 gcc를 사용하여 C를 설명한다. 그래서 컴파일, 링킹의 개념부터 파이프, 포크, 프로세스, 스레드 등의 요소도 학습하며 C를 배우게 된다.  또한 이 과정에서 Linux에 친숙해질 수 있으니 일석이조라 할 수 있지 않을까? (적어도 대학교에 강의를 다니는 강사에게서 요즘 학생들은 Linux를 쓸 줄도 모른다는 이야기를 듣지는 않게 될 테니깐 말이다.) 사실 Linux를 모르고 C를 한다는 것 자체가 모순되는 말이다.

이런 점에서 C를 가르치는데 이 책을 선택하였고, C를 처음 배우는 사람들에게도 추천한다. (하지만 완전 초급자용은 아니다. 최소한 if, for, while등의 기본은 갖추고 있어야 한다.)

 

 

 

'Study > ' 카테고리의 다른 글

C언어 펀더멘탈  (0) 2014.12.30
Posted by shany0_0
,

C언어 펀더멘탈

Study/책 2014. 12. 30. 22:36

C언어 펀더멘탈


<책소개>

C에 대한 오해와 선입견을 버리도록 돕는 책! 

이 책은 C 언어를 관통하는 철학과 알고리즘을 소개한다. 많은 프로그래머들이 프로그래밍 철학과 C 언어 자체에 대한 이해가 결여된 상태에서 프로그램을 작성하면서도 '돌아가기만 하면 그만이다'라는 생각을 한다. 그러나 겉으로 멀쩡해 보이는 프로그램 안에 실제로 얼마나 많은 오류들이 숨어 있는지 생각해본 적이 있는가? 

이하 생략...


C언어 표준을 오랫동안 공부해온 저자가 이를 한국어로 풀어서 설명한 책이다. C언어 표준문서를 직접 읽을 수도 있지만, 영어나 구성 등으로 어려움을 느낀다면 이 책을 추천한다. 이 책의 내용은 초보자가 읽기에는 난이도가 있는 내용이며, 그 양도 만만치 않다. 하지만 그만큼의 가치가 있는 책이다. 현재는 절판된 상태이지만, 도서관 등에서 구할 수 있다.


다음의 코드가 왜 잘못되었는지 모른다면, 한번쯤 읽어보길 권한다.


if('A' <= c && c <= 'Z' || 'a' <= c && c <= 'z')

...


int a[3][4];

int * pi = a[0];

pi[4];

pi+5;

...



'Study > ' 카테고리의 다른 글

Head First C  (0) 2015.01.04
Posted by shany0_0
,