2017-02-23 1 views
5

printf % p 형식 ​​지정자에 대한 플래그로 '0'이 추가 되었습니까? Ideone에 또한% p의 printf 형식 지정자 플래그 '0'이 맞는지 여부는?

#include <stdio.h> 
int main() 
{ 
    int a = 42; 
    void* p = &a; 
    printf("Pointer address: %08p", p); 
    return 0; 
} 

.

은 상기와 비슷한 코드를 컴파일, 내가 경고 없어 또는 무엇이든지의 Microsoft Visual C++ 2015 만 GCC 5.4.0에서 경고에서 :

"경고 : '% p를'사용 '0'플래그

0 : 정수 및 부동 소수점 숫자 변환, 앞에 0 공간 문자 대신 패드에 필드를 사용 gnu_printf 형식 [-Wformat] "

cppreference printf에서 읽기, 나는 것을 알 수있다. 정밀도가 명시 적으로 지정된 경우 정수 숫자의 경우 무시됩니다. 의 경우이 플래그를 사용하는 다른 변환으로 인해 정의되지 않은 동작이 발생합니다. - 플래그가있는 경우는 이 무시됩니다.

필자가 해석 할 수있는 한 % p는 포인터 주소에 대한 것으로, 결국 정수 값이므로이 정의되지 않은 동작은 % p에 적용됩니까?
그렇지 않은 경우 GCC -Wformat 경고가 표시되는 이유는 무엇입니까?

+0

oook을, 그래서 왜 downvote? – roalz

+0

코드가 근본적인 이유 때문에 컴파일되지 않는 난센스이기 때문에 나는 추측 할 수 있을까요? printf ("포인터 주소 : % 08p", return 0;'실제 코드 나 실제 예를 복사하여 붙여 넣기하지 말고 – Lundin

+0

Jez, 맞습니다. Ideone에서 복사하여 붙여 넣기가 작동하지 않는다는 것을 발견했습니다. 내가 예상했던대로, 편집했다. – roalz

답변

5

%p 모든

포인터가 숫자 표현을 할 수 있지만, 표준은 고려하지 않습니다 포인터 중요한 데이터 유형 후 정수입니다 포인터 주소입니다. 따라서 %08p 형식을 사용하면 정의되지 않은 동작이 발생합니다.

당신은 부호없는 정수로로 포인터를 변환 한 다음 인쇄, using uintptr_t data type하여이 문제를 해결할 수 있습니다

#include <cinttypes> 
#include <cstdint> 

int main() { 
    int i = 123; 
    void* p = &i; 
    printf("%08" PRIxPTR "\n", (uintptr_t)p); 
    return 0; 
} 

Demo.

4

퍼센트 p를

가 아니 포인터 뷰의 C/C++ 타입 시스템의 관점에서 정수가 결국 정수이다 포인터 어드레스위한 것이다.

포인터는 산술 적이거나 정수형이 아니며, std::is_integral, std::is_arithmetic을 참조하십시오.