From: Peter R. <pe...@ly...> - 2009-08-25 09:06:11
|
Den 2009-08-25 10:41 skrev Markus Selve: >> Hello! >> >> I have some trouble which can be summarized with this simple program: >> >> $ cat scan.c >> #include <stdio.h> >> int main(void) >> { >> void *p; >> char buf[100]; >> >> snprintf(buf, sizeof(buf), "%p", &p); >> printf("%s\n", buf); >> sscanf(buf, "%p", &p); > > I'm not 100% sure here, but I think this is one pointer indirection too > much. '*p' is the variable to actually store the pointer in. sscanf needs > the pointer to '*p' to be able to store the value there. The pointer to > '*p' is simply 'p', and not '&p'. You are wrong. The program prints the address of the p pointer variable to a buffer. It then scans that buffer and stores the result in the p pointer (i.e. not in the address of the pointer). I.e. it is intended that p point to the address of p after these operations. I could have used some other address in the snprintf call, e.g. snprintf(buf, sizeof(buf), "%p", buf); and it would still not come out with the two expected identical output lines. >> printf("%p\n", p); > > If I'm right with the above, then the value sscanf read from 'buf' was > stored in '*p'. So printf now needs '*p' as an argument, not 'p'. You are confused. Try the same program with _snprintf instead of snprintf if you like. This is just a destilled silly program designed to be a simple test case. Don't expect it to do anything otherwise useful. I wrote it because I have a real world libraries which fail because of this unexpected behaviour. >> return 0; >> } >> $ gcc -o scan scan.c >> $ ./scan >> 0x22ff6c >> 00000000 > >>From your second mail: > >> Oops, sorry. Thinking about it some more, I think I expect >> 0022FF6C >> 0022FF6C > > No, I think you get the '0x' added. From the printf man page: > > p The void * pointer argument is printed in hexadeci > mal (as if by %#x or %#lx). > > And '#' means: > > # The value should be converted to an ''alternate > form''. ... > ... > For x and X conversions, > a non-zero result has the string '0x' (or '0X' for > X conversions) prepended to it. ... > ... I don't care about the exact format %p produces, but sscanf is required to understand what snprintf produces. Quoting [1]: "p Matches an implementation-defined set of sequences, which shall be the same as the set of sequences that is produced by the %p conversion specification of the corresponding fprintf() functions." No hash mark needed as far as I can tell. I still claim that the snprintf fixup function is buggy wrt %p. [1] http://www.opengroup.org/onlinepubs/009695399/functions/scanf.html Cheers, Peter |