void에서 &&는 무엇을 의미합니까 * p = && abc;


102

코드 조각을 발견했습니다 void *p = &&abc;. 여기서의 의미는 무엇입니까 &&? rvalue 참조에 대해 알고 있지만 &&이 컨텍스트에서 사용되는 것은 다릅니다. 무엇을 &&의미 void *p = &&abc;합니까?


14
이거 어디서 봤어?
user541686

3
나는 또한 당신이 이것을 본 곳을 알고 싶습니다.
Flavius

답변:


154

&&현재 함수에 정의 된 레이블의 주소를 가져 오는 gcc의 확장 입니다.

void *p = &&abc 표준 C99 및 C ++에서는 불법입니다.

이것은 g ++로 컴파일됩니다.


42
이제 gcc가 기본적으로 -pedantic을 가지고 있다면 모든 사람이 얼마나 더 나은 프로그래머가 될지 상상해보십시오. 그런 다음 사람들은 누에 대한 관련없는 정보 대신 C를 배웁니다.
Lundin

4
무슨 해킹. 레이블 포인터에 대한 새로운 구문을 발명하는 경우를 사용하는 대신 새로운 유형도 발명해야합니다 void*.
Mark Ransom

1
@Prasoon Saurav : 반대표를 던진 사람은 아마이 기능을 승인하지 않았을 것이고 당신에게 그것을 제거하고있을 것입니다.
Chuck

@Lundin : 대부분의 컴파일러도 마찬가지입니다. __forceinline? __declspec(naked)? 내가 가장 좋아하는 MSVCism 중 하나 template<typename T> class X { friend T; }는 잘못된 C ++ 03입니다.
Sebastian Mach

두 번째 링크가 끊어졌습니다.
Cœur

96

그것을 찾는 방법

이것이 라벨의 주소이며 GCC와 관련된 기능 입니다.

int main(void) {
    void* startp;
s:
    startp = &&s;
    printf("the assignment above starts at address %p\n", startp);
    return 0;
}

테스트를 통해 직접 알아낼 수 있습니다.

int main(void) {
    void* startp;
    int a;
    startp = &&a;
    printf("startp=%p\n", startp);
    return 0;
}

이 경우 GCC는 다음과 같이 말합니다.

오류 : 레이블 'a'가 사용되었지만 정의되지 않았습니다.

후드 아래-조립

이것을 이해하기 위해서는 어셈블러를 알아야하지만 레이블 주소가 무엇을 의미하는지 설명하려고합니다.

OS가 디스크에서 .exe 파일을로드 한 후 "로더"라는 운영 체제의 구성 요소 (윈도우에는 "PE 로더", Linux에는 "ELF 로더"또는 다른 프로그램이 있습니다. 커널), 해당 프로그램의 "가상화"를 수행하여 프로세스로 전환합니다.

이 프로세스는 이것이 RAM에서 유일한 것으로 간주하고 전체 RAM (즉, 32 비트 시스템에서 0x00000000-0xFFFFFFFF)에 액세스 할 수 있습니다.

(위는 무슨 일이 일어나고 있는지에 대한 짧은 오버 와이트입니다. 당신은 그것을 완전히 이해하기 위해 정말로 어셈블리를 배워야합니다.

이제 소스 코드의 레이블은 기본적으로 주소입니다. "고토 레이블;" 해당 주소로 점프하는 것 외에는 아무것도하지 않습니다 ( 어셈블리 의 명령어 포인터 에 대해 생각해보십시오 ). 이 레이블은이 RAM 주소를 저장하며, 그 주소를 찾을 수있는 방법입니다.

ASM을 배운 후에는 해당 주소 .text가 실행 파일 섹션 내의 명령어를 가리킴을 알게 될 것 입니다. .text섹션으로 실행될 프로그램 (이진) 코드를 보유하고있는 것입니다.

다음을 사용하여이를 검사 할 수 있습니다.

objdump -x a.out

실용적인 예

GCC에 설명 된대로 이를 사용하여 점프 테이블을 초기화 할 수 있습니다. re2c ( 매개 변수 참조) 와 같은 일부 스캐너 생성기 는 이를 사용하여보다 컴팩트 한 스캐너를 생성합니다. 동일한 기술을 사용 하는 파서 생성기 가있을 수도 있습니다 .-g


4
-std = c99 -pedantic으로 컴파일합니다.
Lundin

2
그것은 GCC 확장이며 언어의 핵심 부분이 아니라는 것을 언급하는 것이 매우 중요합니다
jalf

1
그것은 꽤 인상적인 Flavius입니다.
Octavian A. Damiean

1
저는 이런 종류의 대답을 좋아합니다. 더 많은 사람들이 단순히 말하는 것보다 대답을 찾는 방법을 배워야합니다.
Letseatlunch 2011-06-21

1
깊이있는 설명에 감사드립니다. 어셈블리 관련 분석에 감사드립니다.
CᴴᴀZ 2013
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.