General TC > Programming & Scripting - Unofficial
How to define a variable compatible with npos in C++
Rich:
Several programs in Xprogs.tcz use a .find() instruction which returns
a value which is compatible with npos.
The value returned is unsigned and its width depends on the target it's
compiled for. Here is an example:
--- Code: ---string cmdline, target_boot_option;
ifstream proc_cmdline("/proc/cmdline");
getline(proc_cmdline, cmdline);
proc_cmdline.close();
target_boot_option = "lst=";
int sloc = cmdline.find(target_boot_option);
if ( sloc == string::npos ) {
onbootName = "onboot.lst";
} else {
int eloc = cmdline.find(" ",sloc);
int work = eloc - (sloc + target_boot_option.length());
onbootName = cmdline.substr(sloc+target_boot_option.length(),work);
}
--- End code ---
When compiled, the following warning is issued:
--- Code: --- warning: comparison of integer expressions of different signedness: 'int' and 'std::__cxx11::basic_string<char>::size_type' {aka 'unsigned int'} [-Wsign-compare]
if ( sloc = string::npos )
--- End code ---
From what I've read:
npos is size_type which is typedef as size_t
exception, if someone writes a custom class and defines it differently
What is the correct C++ way to:
define sloc so it is compatible with npos?
define eloc and work so the math doesn't blow up under other architectures?
I don't really understand C++, so I'm looking for someone who does.
Paul_123:
That is just a compiler warning, C++ should implicitly do that conversion. But to make sure it’s doing what you want, explicitly do the typecasting.
if ( sloc == static_cast<int>string::npos ) {
Paul_123:
looked at the source.
in apps.cxx it uses the cast the other direction
--- Code: --- if ( (long unsigned)sloc == string::npos ) {
--- End code ---
This is a C style typecast. One thing to note is that on aarch64, I do not see the same warning you do.
Rich:
Hi Paul_123
--- Quote from: Paul_123 on May 10, 2025, 10:28:29 AM ---looked at the source.
in apps.cxx it uses the cast the other direction
--- Code: --- if ( (long unsigned)sloc == string::npos ) {
--- End code ---
...
--- End quote ---
Yes, I did that, though I'm not sure if that's a smart way to handle it.
The problem is npos is a constant set to -1 and defined as unsigned.
It is used to indicate the find command failed by returning the largest
address the architecture supports.
sloc can't be an int because it's signed.
It can't be an unsigned int because on x86_64 that's 32 bits.
I'm just concerned that unsigned long causes an unforeseen
problem elsewhere.
I did try these 4 and the compiler didn't complain:
--- Code: --- std::__cxx11::basic_string<char>::size_type loc = cmdline.find("norestore");
std::basic_string<char>::size_type loc = cmdline.find("norestore");
size_t loc = cmdline.find("norestore");
string::size_type loc = cmdline.find("norestore");
--- End code ---
But I don't know enough about C++ to know if any of
them are appropriate.
Paul_123:
I thought you were asking about the compiler warning. not asking was it working right.
string::npos is a very large number. The standard casts it the other way to define it. Take a -1 and cast it unsigned.
I think its working fine. Does this help explain?
--- Code: ---
#include <iostream>
#define NEG1 -1
int main(){
//outputs npos.....very big number
std::cout << std::string::npos << std::endl;
//This gives a compiler warning for the unsigned to signed conversion
int sloc = std::string::npos; //sloc will = -1
std::cout << sloc << std::endl;
// sloc is a -1 casting to a unsigned long: yields the very large number
std::cout << (unsigned long)sloc << std::endl;
//just a few other examples.
//This casts everything as an signed int.
int eloc = (int)std::string::npos;
std::cout << eloc << std::endl;
//This casts everything as a unsigned long
unsigned long ul = std::string::npos;
std::cout << ul << std::endl;
//This is just casting a defined constant.
std::cout << NEG1 << std::endl;
std::cout << (size_t)NEG1 << std::endl;
return 0;
}
--- End code ---
The resulting output
--- Code: ---$ ./cast
18446744073709551615
-1
18446744073709551615
-1
18446744073709551615
-1
18446744073709551615
$
--- End code ---
So what is the problem you are trying to solve?
Navigation
[0] Message Index
[#] Next page
Go to full version