Intel® oneAPI DPC++/C++ Compiler
Talk to fellow users of Intel® oneAPI DPC++/C++ Compiler and companion tools like Intel® oneAPI DPC++ Library, Intel® DPC++ Compatibility Tool, and Intel® Distribution for GDB*
718 Discussions

No warning for unsigned / signed underflow in if statement

mhogstrom
Beginner
464 Views
I got a strange bug using std::vector::size()
underflow for mixing signed and unsigned, 
The comparison then fails. 

I know it is my fault for mixing unsigned and signed.
But std::vector returns a size_type, which in turn is a template of something. I struggled finding the definition, but I assume it is an unsigned of something.

if((size() - 9) >= 0)   // underflow
(-1) >= 0   // TRUE ?!

When I wrote the code I didnt think about it.
If I store the result temporarily in a signed int it works fine.

Below is a PoC

void No_Unisgned_Overflow_Warning() {
  std::vector<char> v(8);
  int adjustIndex = 9;
  if ((v.size() - adjustIndex) >= 0) {
    printf("First!\n");
  }
  int index = v.size() - adjustIndex;
  if (index >= 0) {
    printf("Second!\n");
  }
}

The result of the subtraction is probably expanded to the unsigned datatype.
But then the comparison >= doesn't make sense.
It is always true

The string "First" is printed but not "Second".
I think it would help if we get a warning about signed/unsigned mismatch in the comparison, or always true condition. I am compiling with Intel DPC++ 2025 on Windows.
0 Kudos
4 Replies
Viet_H_Intel
Moderator
316 Views

$icpx t12.cpp &&./a.out
First!

$ icpx t12.cpp -Wsign-conversion
t12.cpp:8:19: warning: implicit conversion changes signedness: 'int' to 'size_type' (aka 'unsigned long') [-Wsign-conversion]
8 | if ((v.size() - adjustIndex) >= 0) {
| ~ ^~~~~~~~~~~
t12.cpp:11:26: warning: implicit conversion changes signedness: 'int' to 'size_type' (aka 'unsigned long') [-Wsign-conversion]
11 | int index = v.size() - adjustIndex;
| ~ ^~~~~~~~~~~
2 warnings generated.

$ icpx t12.cpp -Wtautological-unsigned-zero-compare
t12.cpp:8:32: warning: result of comparison of unsigned expression >= 0 is always true [-Wtautological-unsigned-zero-compare]
8 | if ((v.size() - adjustIndex) >= 0) {
| ~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~
1 warning generated.

$ cat t12.cpp
#include <iostream>
#include <vector>
using namespace std;
int main()
{
std::vector<char> v(8);
int adjustIndex = 9;
if ((v.size() - adjustIndex) >= 0) {
printf("First!\n");
}
int index = v.size() - adjustIndex;
if (index >= 0) {
printf("Second!\n");
}
return 0;
}

0 Kudos
mhogstrom
Beginner
291 Views

We are not using the same compiler or platform. a.out is un*x filename
I am using Visual Studio 2022, DPC++, under Windows.

mhogstrom_0-1733312721105.pngmhogstrom_1-1733312806829.png

Compiler is set to use Warning level 3 -W3, -Wall doesn't detect it either

0 Kudos
Viet_H_Intel
Moderator
262 Views

Can you try -Weverything? or -Wsign-conversion -Wtautological-unsigned-zero-compare in VS

0 Kudos
mhogstrom
Beginner
222 Views


Now we are talking

It seems the compiler it is using is clang to compile.
"C:\\Program Files (x86)\\Intel\\oneAPI\\compiler\\2025.0\\bin\\compiler\\clang-cl.exe"
If I add "-Wno-error -Wsign-conversion -Wtautological-unsigned-zero-compare"
or -Weverything the warning rightfully appears.

mhogstrom_1-1733391620568.png

 


It seems that Visual Studio passes "-Wall" as option to clang too on the command line.
"-Wall" is usually enough for most development.

Reading https://clang.llvm.org/docs/UsersManual.html#options-to-control-error-and-warning-messages
"Since -Weverything enables every diagnostic, we generally don’t recommend using it. -Wall -Wextra are a better choice for most projects. "

Adding "-Wextra" also shows the warnings, but it seems that "-Wall" doesn't catch the error.

0 Kudos
Reply