Poll; this compiles, and if so, what does it return (I know the answer)

I recently found this typo:

if (name.find('/' != string::npos)) 

Obviously dev was intended for input

 if(name.find('/') != string::npos) 

But I was amazed to find that the error even compiles with -Wall -Werror (did not try with -pedantic )

So coffee test: does it evaluate true or false?

+4
source share
7 answers

'/' is not equal to string :: npos, since npos is required to be negative, and none of the characters in the base execution character set can be negative. Therefore, it will look for the value 1 in the string (presumably anyway) represented by name . This is a rather unusual value for a string, so it is usually not found, which means that it will return std::string::npos , which will be converted to true .

Edit: as Johannes pointed out, although the value assigned by npos must be negative 1 (according to 21.3 / 6), which is assigned size_type, which must be unsigned, so the result will not be negative. Usually this has no real meaning: - '/' will be compared with npos using unsigned arithmetic, so the only way they could have the same value is if 1) '/' was encoded as -1 (not allowed as above) or char, has the same range as size_type.

In theory, the standard allows char to have the same range as other integral types. In fact, quite a lot of I / O depends on EOF having a value that could not have come from the file, which basically meets the requirement that char have a range that is less than int and not only less than or equal (as the standard requires )

This leaves one loophole, although this is usually quite terrible: char and short have the same range, size_type is the same as unsigned short, and int has a larger range than char / short, Providing a char and short value of the same range would not be so terrible, but limiting size_type to the same range as the short one would usually be - typically short - 16 bits, so it would limit the containers to 64K. This restriction was problematic 20 years ago under MS-DOS; it just won't be accepted in most markets today.

+3
source

It depends on if name starts with char equal to 1.

It is not surprising that it compiles; there is nothing wrong with that. '/' != std::string:npos evaluates to true, and the only find overload that will work is the version of char c, size_t pos , since bool can be converted to an integer.

So now we are looking for (char)1 , and what is returned depends on the string. If it starts with (char)1 , it returns 0 and this value is false. In any other case, it returns a nonzero integer or true.

+1
source

'/'! = string :: npos evaluates to true. true is assigned the value int (value = 1). find probably does not find the value 1. If the expression probably returns the string :: npos, which is usually -1, which is not zero, and therefore true. My guess: true.

+1
source

I would say false if the name does not contain a char with a value of 0x01.

0
source

I am surprised that the implicit translation from bool to char did not give a warning ... as far as I can tell, it will return true if the name does not start with '\ 001'.

0
source

It will evaluate true if the name contains char == SOH

otherwise false

0
source

Others have already sent the correct answer: the result of a boolean expression must be 1 (true), because '/' must have a value less than unsigned string::npos (defined as the largest value a size_t can be saved). Since 1 is an integer, and since 1 cannot be an address, the compiler detects the only string::find() overload that it can call is a number with char c, size_t pos .

But this is not the end of the story. Try changing the boolean expression from '/' != string::npos to '/' == string::npos . Now the result of the expression is 0, again an integer. Since there is no overload for string::find() that accepts an int , the compiler should be 0 - but why? It can pass it to char , and it can pass it to a pointer. Both options are valid, so there is an ambiguous call.

So you go: your code changes from a valid function call without warning to an ambiguous function call, changing the operator from != To == .

0
source

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


All Articles