C에서 익명의 구조물은 어떻게 반납해야 합니까?
몇 가지 코드를 시도해 보니 다음 코드가 컴파일되어 있습니다.
struct { int x, y; } foo(void) {
}
익명을 반환하는 함수를 정의하는 것 같습니다.
내 컴파일러로 컴파일하는 경우에만 발생합니까, 아니면 합법적인 C(99)입니까?
그렇다면 반환 문에 대한 올바른 구문은 무엇이며 반환된 값을 변수에 올바르게 할당하려면 어떻게 해야 합니까?
돌아가실 구조물은 익명의 구조물이 아닙니다.C 표준은 익명 구조를 태그를 사용하지 않는 다른 구조의 멤버로 정의합니다.반품하시는 건 태그가 없는 구조인데 회원이 아니기 때문에 익명은 아닙니다.GCC는 태그가 없는 구조를 나타내기 위해 < anonymous >라는 이름을 사용합니다.
함수에 동일한 구조를 선언하려고 한다고 가정해 보겠습니다.
struct { int x, y; } foo( void )
{
return ( struct { int x, y; } ){ 0 } ;
}
GCC는 '구조체 <익명>' 유형을 반환할 때 호환되지 않는 유형이지만 '구조체 <익명>'이 예상된다는 불만을 제기합니다.
그 종류들은 호환이 안 되는 것 같습니다.표준을 살펴보면 다음과 같습니다.
6.2.7 호환 형식과 복합 형식
1: 두 종류는 종류가 같다면 호환되는 종류가 있습니다.두 가지 유형이 호환되는지 여부를 결정하는 추가 규칙은 유형 지정자의 경우 6.7.2, 유형 한정자의 경우 6.7.3 및 선언자의 경우 6.7.6에 설명되어 있습니다.또한 별도의 번역 단위로 선언된 두 개의 구조, 결합 또는 열거형은 태그 및 멤버가 다음 요구 사항을 충족하는 경우 호환됩니다.하나가 태그로 선언된 경우, 다른 하나는 동일한 태그로 선언됩니다.둘 다 각각의 번역 단위 내의 어느 곳에서든 완료된 경우, 다음과 같은 추가 요건이 적용됩니다. 각 해당 구성원 쌍이 호환되는 유형으로 선언되도록 구성원 간에 일대일 대응 관계가 있어야 합니다. 한 쌍의 구성원이 정렬 지정자로 선언된 경우, 다른 한 쌍의 구성원은 i입니다.s는 동등한 정렬 지정자로 선언되며, 쌍의 한 멤버가 이름으로 선언되면 다른 멤버는 동일한 이름으로 선언됩니다.2개의 구조물에 대해서는 동일한 순서로 해당 부재를 선언합니다.두 구조 또는 조합의 경우 해당 비트 필드의 너비가 동일해야 합니다.두 개의 열거에 대해 해당 구성원의 값은 동일해야 합니다.
두 번째 굵은 부분은 두 구조가 모두 이 예와 같이 태그가 없는 경우 해당 부분 다음에 나열된 추가 요구 사항을 따라야 한다고 설명합니다.그러나 첫 번째 굵은 부분이 눈에 띄면 이들은 별도의 번역 단위에 있어야 하며 예제의 구조는 그렇지 않습니다.그래서 그들은 호환되지 않고 코드도 유효하지 않습니다.
구조를 선언하고 이 기능에 사용하면 코드를 수정하는 것은 불가능합니다.태그를 사용해야 하는데, 이는 두 구조가 동일한 태그를 가져야 한다는 규칙을 위반하는 것입니다.
struct t { int x, y; } ;
struct { int x, y; } foo( void )
{
struct t var = { 0 } ;
return var ;
}
GCC가 다시 불만을 제기합니다. 'struct' 형식을 반환할 때 호환되지 않는 형식이지만 'struct <anonymous>'가 필요했습니다.
이것은 내 버전의 GCC에서 작동하지만, 완전한 해킹처럼 보입니다.고유한 구조 태그를 생성하는 추가적인 복잡성을 처리하고 싶지 않은 자동 생성 코드에서 유용할 수도 있지만, 저는 그 합리화까지도 생각해 내려고 노력하고 있습니다.
struct { int x,y; }
foo(void) {
typeof(foo()) ret;
ret.x = 1;
ret.y = 10;
return ret;
}
main()
{
typeof(foo()) A;
A = foo();
printf("%d %d\n", A.x, A.y);
}
또한 컴파일러에 존재하는 ()의 종류에 따라 다릅니다. GCC와 LLVM은 이를 지원하는 것처럼 보이지만 많은 컴파일러가 지원하지 않습니다.
당신은 아마도 명시적으로 할 수 없을 것입니다. return
값단,의부계값는한 (a지를)한는 )를 한)typeof
결과의 유형을 가져오려면 확장을 선택합니다.)
이 이야기의 교훈은 당신이 익명을 반환하는 함수를 선언할 수 있다고 하더라도 struct
, 당신은 절대로 그런 짓을 해서는 안됩니다.
대신에, 에, 의 .struct
코드:
struct twoints_st { int x; int y; };
struct twoints_st foo (void) {
return ((struct twoints_st) {2, 3});
};
, 시 으로는 가 은 으로 되지 입니다 으로 입니다 되지 으로는 return
(예를 들어, 당신은 전화를 할 수 있습니다.exit
그안에 but). 왜하려고 합니까(그런데 왜 다음을 코드화하고 싶으십니까? (아마도 합법적일 것입니다.
struct { int xx; int yy; } bizarrefoo(void) { exit(EXIT_FAILURE); }
방금 발견한 해킹 없이 C++14의 익명 구조를 반환하는 방법이 있습니다.
할 것 (C++ 11 할 할 )
의는수수nintersect()
다std::pair<bool, Point>
그것은 매우 설명적이지 않기 때문에 나는 결과에 대한 맞춤형을 만들기로 결정했습니다.
제가 따로 만들 수도 있었는데요struct
하지만 저는 이 특별한 경우에만 필요하기 때문에 가치가 없었습니다. 그래서 익명의 구조물을 사용했습니다.
auto intersect(...params...) {
struct
{
Point point;
bool intersects = false;
} result;
// do stuff...
return result;
}
그리고 이제, 못생긴 것 대신에
if (intersection_result.first) {
Point p = intersection_result.second
훨씬 더 멋진 모습을 사용할 수 있습니다.
if (intersection_result.intersects) {
Point p = intersection_result.point;
반환 인수 사양에 구조를 정의할 수 있습니다.또한 간단한 설명을 위해 C99에 소개된 복합 리터럴을 사용할 수 있습니다.
#include<stdio.h>
struct foo { int x, y; }
foo( void )
{
return (struct foo){ 1, 2 } ;
}
int main()
{
struct foo res = foo();
printf("%d %d\n", res.x, res.y);
}
인쇄:
1 2
이 코드는 경고 없이 C99에 대해 현학적 모드로 컴파일됩니다.태그 이름은 함수와 동일합니다.이것은 구조물의 네임스페이스와 전역 객체가 분리되어 있기 때문에 작동합니다.이렇게 하면 실수로 이름이 충돌할 가능성을 최소화할 수 있습니다.당신은 다음과 같은 것을 사용할 수 있습니다.foo_result
그것이 더 적합하다고 생각한다면요.
또는 무한 재귀를 만들 수도 있습니다.
struct { int x, y; } foo(void) {
return foo();
}
나는 그것이 완전히 합법적이라고 생각합니다.
이것은 GCC의 최신 버전까지 작동합니다.매크로로 동적 배열을 만드는 데 특히 유용합니다.예를 들어 다음과 같습니다.
#define ARRAY_DECL(name, type) struct { int count; type *array; } name
그러면 realoc 등으로 배열을 만들 수 있습니다.이 방법은 모든 유형을 사용하여 동적 배열을 만들 수 있기 때문에 유용합니다.그렇지 않으면, 당신은 결국 많은 양을 사용을 하게 될 것입니다.void *
그리고 쓰기 기능은 실제로 캐스트 같은 것으로 값을 돌려받는 기능을 합니다.매크로로 이 모든 것을 단축할 수 있습니다. 그것이 매크로의 아름다움입니다.
언급URL : https://stackoverflow.com/questions/27858240/how-can-i-return-an-anonymous-struct-in-c
'programing' 카테고리의 다른 글
Choosen 플러그인을 사용하여 선택 항목 (0) | 2023.09.09 |
---|---|
jQuery slideUp and slideDown에 해당하는 CSS3? (0) | 2023.09.09 |
jQuery에서 "hover"의 바인딩을 해제하려면 어떻게 해야 합니까? (0) | 2023.09.09 |
iOS - Xcode에서 파일 소유자 및 First Responder란 무엇입니까? (0) | 2023.09.09 |
모바일 Safari에서 클릭 이벤트 시 300ms 지연 제거 (0) | 2023.09.09 |