0

I wrote the following code example and I've had to use -fpermissive to skip the error/warning

#include <iostream>
#include <vector>
using namespace std;

int endOfProgram(){
    printf("\n\npress return key to close the program...");
    char end[2];
    fgets(end, 2, stdin);
    return 0;
}

void pointerTest(vector<int> * pointer){
    printf("%d\n", pointer);
    printf("%#x\n", (unsigned)pointer);
    for (auto it = (*pointer).begin(); it < (*pointer).end(); it++)
        printf("%d ", *it);
}

int main(){
    vector<int> numbers = { 1, 2, 3, 4, 5, 6 };
    pointerTest(&numbers);
    endOfProgram();
}

error/warning message:

@test:~/workspace $ make
g++ -std=c++11 pointerTest.cc -o pointerTest -fpermissive
pointerTest.cc: In function ‘void pointerTest(std::vector<int>*)’:
pointerTest.cc:13:24: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘std::vector<int>*’ [-Wformat=]
  printf("%d\n", pointer);
                        ^
pointerTest.cc:14:28: warning: cast from ‘std::vector<int>*’ to ‘unsigned int’ loses precision [-fpermissive]
  printf("%#x\n", (unsigned)pointer);
                            ^

obviously these two lines are problematic...

printf("%d\n", pointer);
printf("%#x\n", (unsigned)pointer);

the question: How can I write these lines, in order to avoid using -fpermissive?

Ubica
  • 1,011
  • 2
  • 8
  • 18

2 Answers2

3
  1. Don't use %d to print out a pointer. It's undefined behaviour.
  2. Use the %p format specifier to print out a pointer, rather than trying to cast it to an integer.
Brian Bi
  • 111,498
  • 10
  • 176
  • 312
2

There's a special escape for pointers:

printf("%p\n", pointer);

Alternatively, but strictly less preferred:

printf("%lu\n", uintptr_t(pointer));

The former would print something like 0x7fffc3488bbc while the latter would print a decimal version 140736469699516.

Barry
  • 286,269
  • 29
  • 621
  • 977
  • `%lu` means `unsigned long`. The proper format specifier for `uintptr_t` is the macro `PRIuPTR` defined in ``. – Brian Bi Dec 14 '14 at 23:58
  • 1
    @Brian I'll worry about being cross platform when I have to... for now `"%lu\n"` is way more obvious than `"%" PRIuPTR "\n"`. – Barry Dec 15 '14 at 00:01
  • thanks... so basically `printf("%" PRIuPTR "\n", uintptr_t(pointer));` would make it cross platform? – Ubica Dec 15 '14 at 00:08
  • @Ubica Yep. See [this answer](http://stackoverflow.com/a/6299346/2069064) for more info. – Barry Dec 15 '14 at 00:16
  • 1
    The problem with barry's answer is that `lu` is not always the size of `uintptr_t` on all platforms. What worse is that if `ul` is larger, you get a random chunk of stack printed, and if `ul` is smaller and you have other arguments printed, you could crash. Don't treat formatting arguments casually. – Yakk - Adam Nevraumont Dec 15 '14 at 02:08