Why sscanf is not working properly with the bool type

Result of this code:

const char *buff = "*_2D 1"; char field[10]; int flag; sscanf(buff, "%s %d", field, &flag); printf("field:%s flag:%i\n", field, flag); 

there is field:*_2D flag:1

However, changing the int value to bool will produce strange behavior:

 const char *buff = "*_2D 1"; char field[10]; bool flag; sscanf(buff, "%s %d", field, &flag); printf("field:%s flag:%i\n", field, flag); 

Output field: flag:1

Can anyone explain what is going on here? I would think that bool would be interpreted as an int, which apparently there is, but the rest of the line disappears.

+6
source share
6 answers

Imagine if bool is just one byte, not the four (or even eight) that int uses. Then, telling sscanf that &flag is a pointer to an int , it will end up overwriting three or seven bytes elsewhere on the stack, which may be directly on top of your field variable. This space will be filled with 0 bytes, effectively ending your line.

+11
source

bool is a separate type for int and is likely to be a single byte (which on most common platforms is less than int ).

sscanf not type safe; you specify (using the conversion specifier %d ) that you provide the pointer to int , and therefore it assumes that it is safe to write int there. If the actual type is less, you will get undefined behavior; most likely, either other local variables will be overwritten, or the stack frame will be corrupted. In this case, it seems to overwrite the beginning of field with zero bytes of integer value 1 .

+4
source

Could this be because sizeof(bool) sometimes 1 ? So, I don’t know much C ++, but in C this will be undefined behavior.

+3
source

According to spec for sscanf % d description:

Matches an optionally signed decimal integer ... In the absence of a size modifier, the application must ensure that the corresponding argument is a pointer to an int.

Also from the same specification,

if the result of the conversion cannot be represented in the provided space, the behavior is undefined.

Since sizeof (bool) <sizeof (int), you are in the scary zone of Undefined Behavior, and anything can happen.

+2
source

sscanf function failed because bool not int , but char

Try the following:

 const char *buff = "*_2D 1"; char field[10]; char flag; sscanf(buff, "%s %d", field, &flag); printf("field:%s flag:%i\n", field, flag); 

This will give you the same error.

0
source

If you use C ++ (which is similar to your comments), why not use C ++ streams instead of the C scanf -style scanf approach?

 const std::string buff = "*_2D 1"; std::string field; bool flag = false; std::istringstream ss(buff); ss >> field >> flag; std::cout << "field:" << field << " flag:" << flag << std::endl; 
0
source

Source: https://habr.com/ru/post/892749/


All Articles