표현식과 상수는 메모리에 저장되지 않는 경우 어디에 저장됩니까?
Brian W. Kernighan의 C 프로그래밍 언어에서
& 연산자는 메모리 내의 개체(변수 및 배열 요소)에만 적용됩니다.식, 상수 또는 레지스터 변수에 적용할 수 없습니다.
표현식과 상수는 메모리에 저장되지 않는 경우 어디에 저장됩니까?그 인용문은 무슨 뜻입니까?
: :
&(2 + 3)
왜주주 받으 으? ???디에에 보관 ?? ????
C++ C는 C++로 되어 있나요?
이 링크된 질문은 이러한 표현이rvalue
및 all " " " " " 。rvalue
오브젝트에는 주소가 없습니다.
궁금한 점은 이 표현식들이 주소를 검색할 수 없도록 어디에 저장되어 있는가 하는 것입니다.
다음 기능을 고려합니다.
unsigned sum_evens (unsigned number) {
number &= ~1; // ~1 = 0xfffffffe (32-bit CPU)
unsigned result = 0;
while (number) {
result += number;
number -= 2;
}
return result;
}
이제 컴파일러 게임을 하고 손으로 컴파일러를 해보겠습니다.대부분의 데스크톱 컴퓨터가 x86을 사용하기 때문에 x86을 사용하고 있다고 가정합니다.(x86은 인텔 호환 CPU용 명령어 세트입니다.)
컴파일 시 이 루틴이 어떻게 표시되는지 간단한(최적화되지 않은) 버전에 대해 살펴보겠습니다.
sum_evens:
and edi, 0xfffffffe ;edi is where the first argument goes
xor eax, eax ;set register eax to 0
cmp edi, 0 ;compare number to 0
jz .done ;if edi = 0, jump to .done
.loop:
add eax, edi ;eax = eax + edi
sub edi, 2 ;edi = edi - 2
jnz .loop ;if edi != 0, go back to .loop
.done:
ret ;return (value in eax is returned to caller)
코드의 입니다.0
,2
,1
는 실제로 ㅇㅇㅇㅇ.1
는 전혀 표시되지 컴파일러 경우 저만)는 하고 있습니다.~1
그리고 그 결과를 코드에 사용합니다.
CPU 명령의 주소는 취득할 수 있지만, 그 일부의 주소는 취득할 수 없는 경우가 있습니다(x86에서는 취득할 수 있는 경우가 있습니다만, 그 외의 많은 CPU에서는 취득할 수 없는 경우가 있습니다).코드 주소는 데이터 주소와 근본적으로 다릅니다(이 때문에 함수 포인터(코드 주소)를 통상의 포인트로 취급할 수 없습니다).er(데이터 주소).일부 CPU 아키텍처에서는 코드 주소와 데이터 주소가 완전히 호환되지 않습니다(단, 대부분의 최신 OS에서 사용하는 x86의 경우는 그렇지 않습니다).
「 」라고 하는 에 주의해 .while (number)
while (number != 0)
그거0
컴파일된 코드에 전혀 표시되지 않습니다. 말은 은근데, 이 말이 내포되어 요.jnz
instruction(지시) 그 주소를 받을 수 없는 또 입니다.0
요. - 그대로 어디에도 없어요 - 어디에도 없어요. 말 그대로 어디에도 없어요.
이걸로 더 명확해졌으면 좋겠어요.
주소를 검색할 수 없도록 이러한 표현식은 어디에 저장됩니까?
질문 형식이 올바르지 않습니다.
개념적으로
동사는 안 되고 명사의 소유권은 왜 논의하느냐고 묻는 것과 같다.명사는 소유될 수 있는 것들을 가리키고, 동사는 행해지는 행동들을 가리킨다.당신은 어떤 행동을 소유하거나 어떤 것을 수행할 수 없습니다.
언어 사양의 관점에서
표현식은 처음부터 저장되지 않고 평가됩니다.컴파일러에 의해 컴파일 시에 평가될 수도 있고 프로세서에 의해 실행 시에 평가될 수도 있습니다.
언어 구현에 있어서
스테이트먼트를 고려하다
int a = 0;
은 두 작업을 합니다. 변수인 '이것'을 합니다.첫 번째로 정수 변수를 선언합니다.
a
이것은, 수신할 수 있는 주소로 정의되어 있습니다.컴파일러는 특정 플랫폼에서 의미 있는 모든 작업을 수행할 수 있으며 사용자가 다음 주소를 사용할 수 있도록 합니다.a
.다음으로 변수 값을 0으로 설정합니다.이는 값이 0인 정수가 컴파일된 프로그램 어딘가에 존재함을 의미하지는 않습니다.일반적으로 다음과 같이 구현될 수 있습니다.
xor eax,eax
XOR) 또는 XOR(배타적)입니다.
eax
스스로 등록합니다.이 결과는 항상 0이 됩니다. 그 전에 무엇이 있었든 말이죠. 가치의 것은 .0
리터럴에 하도록 컴파일된 합니다.0
출처에 적어놨어요
제가 가가 that that , 편 as as as as.a
위는 주소를 받을 수 있는 것입니다.주소를 받지 않으면 실제로 주소가 없을 수 있습니다.예를 들어,eax
이 예에서 사용되는 레지스터에는 주소가 없습니다. 것을 할 수 , 「 」는 「 」를 참조해 .a
그 레지스터에서 평생을 살 수 있지만 주 기억에는 존재하지 않습니다.로 하다라는 요.&a
지정 하도록 합니다.a
의 값입니다.
참고로 표현식 주소를 사용할 수 있는 다른 언어를 쉽게 선택할 수 있습니다.
컴파일은 보통 기계에서 실행 가능한 출력이 이러한 구조를 대체하면 이러한 구조를 폐기하기 때문에 해석될 수 있습니다.를 들어 Python에는 이 있고 Python에는 런타임 인스펙션이 .code
★★★★★★★★★★★★★★★★★★.
또는 LISP에서 시작하여 확장하여 S-expression에 대한 주소 지정 연산을 제공할 수 있습니다.
두 사람의 공통점은 C가 아니라는 것입니다.설계나 정의상 이러한 메커니즘은 제공되지 않습니다.
표현식과 상수가 메모리에 없는 경우 어디에 저장됩니까?
일부(실제로 많은) 경우 상수 식이 전혀 저장되지 않습니다.특히 컴파일러 최적화에 대해 생각해 보면, CppCon 2017: Matt Godbolt의 강연 "What Has My Compiler Done Me Recents"를 참조할 수 있습니다. 컴파일러 뚜껑의 볼트 해제"
「C」를 가지는 는, 다음과 .2 + 3
대부분의 최적화 컴파일러는 5로 계속 접을 수 있으며, 이 5개의 상수는 코드 세그먼트의 머신 코드 명령(비트필드 등) 안에 있고 메모리 위치조차 제대로 정의되어 있지 않을 수 있습니다.이 상수 5가 루프 제한일 경우 일부 컴파일러는 루프 롤링을 수행할 수 있으며 이 상수는 바이너리 코드에 더 이상 표시되지 않습니다.
이 답변도 참조해 주세요.
C11은 영어로 작성된 사양이므로 주의하시기 바랍니다.n1570 표준을 읽어보십시오.C++11(또는 그 이후)의 훨씬 더 큰 사양도 읽어 보십시오.
상수의 주소 취득은 C(및 C++)의 의미론에서는 금지되어 있습니다.
이러한 표현은 결국 기계 코드의 일부가 됩니다..2 + 3
레지스터 A에 5를 로드하다CPU ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★」
주소를 식에 넣는 것은 그다지 의미가 없습니다.가장 가까운 것은 함수 포인터입니다.식은 변수 및 개체와 동일한 의미로 저장되지 않습니다.
표현식은 실제 기계 코드에 저장됩니다.물론 표현식이 평가되는 주소를 찾을 수 있지만, 그렇게 하는 것은 말이 되지 않습니다.
조립에 대해 조금 읽어보십시오.식은 텍스트 세그먼트에 저장되며 변수는 데이터 또는 스택과 같은 다른 세그먼트에 저장됩니다.
https://en.wikipedia.org/wiki/Data_segment
표현식은 CPU 명령인 반면 변수는 순수 데이터라는 것도 설명할 수 있습니다.
고려해야 할 것이 하나 더 있습니다.컴파일러는 종종 사물을 최적화한다.다음 코드를 고려하십시오.
int x=0;
while(x<10)
x+=1;
이 코드는 다음과 같이 최적화됩니다.
int x=10;
그럼 주소는 어떻게 될까요?(x+=1)
우 it it에도 없기 전혀 없습니다.기계 코드에는 존재하지 않기 때문에, 정의상, 주소가 전혀 없습니다.
언급URL : https://stackoverflow.com/questions/47884244/where-are-expressions-and-constants-stored-if-not-in-memory
'programing' 카테고리의 다른 글
요소에 ID가 없을 때 vuej에서 v-for를 처리하는 방법 (0) | 2022.06.01 |
---|---|
C/C++ 포함 헤더 파일 순서 (0) | 2022.06.01 |
Vuex의 4가지 상태를 구별하는 방법 (0) | 2022.06.01 |
Vue.js 2: .vue 파일에서 Vue 컴포넌트를 초기화(구성)하는 방법 (0) | 2022.06.01 |
Vuejs: 킵 얼라이브를 사용한 자 라우터 표시 컴포넌트의 라이프 사이클 후크 (0) | 2022.06.01 |