같은 멤버를 가진다면 A 구조체에서 B 구조체로 묵시적 형변환이 가능한건가요?
글쓴이: dreamist / 작성시간: 금, 2014/01/17 - 3:08오후
내용물이 같고 이름이 다른 두 구조체를 사용할 때,
B구조체를 입력받는 함수에 A구조체를 넣으면 묵시적 형변환이 되는건가요?
실행에 문제가 없고, 원하던 출력을 보여줘서 형변환이 일어나는 것 같은데
이해가 되지 않네요.
이렇게 같은 내용물을 가지고 있지만 다른 이름을 가진 구조체를 사용하기 위해서는
어떻게 해야되나요?
/* A.h */ #pragma once #include <stdio.h> typedef struct AaMat{ int row; int col; } AaMat;
/* B.h */ #pragma once #include <stdio.h> typedef struct BbMat{ int row; int col; } BbMat; int GetMatD(BbMat mat);
/* B.c */ #include "B.h" int GetMatD(BbMat mat) { return mat.row*mat.col; }
/* main.c */ #include "A.h" #include "B.h" int main(void) { AaMat amat; amat.row=3; amat.col=2; printf("D : %d\n",GetMatD(amat)); return 0; }
Forums:
저렇게 돌려봤는데 실행이 안되네요
위에 코드를 직접 돌려보니 실행이 안되네요;
그래서 코드를 다시 살펴보니 개념을 가져온 코드에서는
동적할당으로 처리하고, 함수의 입력을 void*로 해서 받았네요;;
그래서 내용물이 같은 구조체의 처리에는 문제가 없다는 것은 알겠는데요
이렇게 같은 내용물을 가지고, 이름이 다른 구조체를 사용할 때,
이렇게 입력을 void* 로 받는 것 말고 다른 방법은 없나요??
C는 이름이나 타입이 아닌 구조를
C는 이름이나 타입이 아닌 구조를 대입합니다
파스칼이나 Cpp랑은 다르죠
감사합니다.
묵시적 형변환은 여기서 가능하지 않은데,명시적 형변환으로 처리하니까 결과가 나오네요.
C가 이름이나 타입이 아닌 구조를 대입해서 가능한거라고 볼 수 있겠네요.
근데 이런 경우에는 어떻게 하는게 가장 좋나요?
같은 내용을 가진 구조체를 따로 만들어야할 이유는
같은 내용을 가진 구조체를 따로 만들어야할 이유는 딱히 없는 것 같은데요?
함수를 따로 정의해야될 필요가 있어서요.
어떤 헤더파일에들서 구조체와 함수를 가져와서 사용해야되는데요.
이렇게 제가 만든 헤더만 가져오면 상관이 없는데 원본 헤더를 가져올 수 있어서요.
그럴때 중복선언 문제가 없고 원본 헤더에 정의된 구조체 이름을 입력으로 받아도 같은 결과가 나와야 되서요.
이 글을 보시면 도움이 될 듯
http://stackoverflow.com/questions/479207/function-overloading-in-c
- 매크로
- 별도의 함수
- C++ 사용(...)
- union을 이용한 추가 구조체 선언.
- 최신 컴파일러가 제공하는 확장 기능 사용.
등등..
일단 plain C에서 완벽하게 해결할 방법은 없는 것 같습니다.
아니면, C가 void*에 대해 암묵적 변환을 지원하는 점을 이용해서 그냥 함수자체를 void*를 받게 작성하셔도 되겠습니다. (다만 이경우 컴파일러에서 타입체크를 해주지 못하게 되겠죠.)
--
감사합니다
원본 파일은 이런식으로 작성되어 있더라고요.
void*를 이용해 받아들인 후 어떤 구조체를 입력받은지 확인
그리고 구조체에 따라 명시적 형변환을 해주더라고요.
아니면 좀 기괴하지만 이런 방법도..
여기서 GetMatD2 안에서 굳이 AaMat를 선언할 이유는 없지만 기존에 만들어둔 함수를 편하게 이용하려면 저렇게 하는게 좋겠지요.
호출할 때 넘기는 구조체 종류가 어찌됐든 필요한 필드가 없거나 타입이 다른 경우 컴파일 에러가 발생하므로 쓸만할겁니다. C에는 어쨌든 액세스 모디파이어는 없으니 항상 모든 멤버를 나열하도록 매크로와 중간함수를 작성하면 더욱 편하겠죠. 포인터를 받는 함수일 경우에도 비슷하게 적용가능하고요. 매크로는 기존 함수 개수만큼 필요하겠지만 중간함수는 하나만 있어도 됩니다.
다만 두 구조체가 완전히 동일한 구조체인지는 보장받을 수 없습니다. 예를 들어 새 구조체가 수퍼셋이라든지, 멤버의 순서가 다르게 정의돼있다든지 하면.. 그래도 의미상 문제는 없으나 바이너리 레벨에선 문제의 소지가 있겠지요. 이것까지 보장받으려면 sizeof 비교랑 메모리 비교 등등을 더 넣으시면 됩니다.
--
이렇게 하면 간단히 해결될 것
이렇게 하면 간단히 해결될 것 같습니다만
그게 문제가..
저 시점에서 AaMat가 무조건 정의돼있는 상황이라면 BbMat를 선언할 필요도 없겠죠. 그냥 AaMat만 쓰면 되니까.
그게 보장이 되지 않기 때문에 저런 귀찮은 작업들이 필요해지는 겁니다. 정의될지 안될지, 정의된다 해도 언제 될지도 모르는데 캐스팅 없이 받아내야 하니까.
--
댓글 달기