解决方案:检查是否有人安装了自定义编译器。
解决方案扩展:我只在服务器上编译,而不是在我的机器上本地编译,当我这样做时,我可以复制@A.K的答案。服务器上的编译是g++和clang++的经典版本。对不起,浪费了人们的时间:(编译器将是delte,我将安装一次官方文件。
这更多的是一个好奇的问题,而不是任何其他问题。当您比较数字类型时,让我们有时假设是int
和size_t
,则会出现这样的警告:error: comparison of integers of different signs:
,当使用-Wsign-compare
和-Werror
时,如果没有-Werror
,则显示为警告。
但是,在开始与一位同事一起工作之后,我注意到不清楚错误是否会实际出现。我之所以注意到这一点,是因为我们如何编写for-loops
。我同事的风格:
for (int i = 0; i < collection.size(); i++)
还有我的风格
for (size_t i = 0; i < collection.size(); ++i)
如果集合是一个标准集合(即向量、映射),则size_t
是返回大小的类型。但是,如果我们使用一个集合,比如pqxx::result
,它的大小为pqxx::result::size_type
或unsigned long
。int i
方法会导致错误。
这对我来说很奇怪,因为我希望这两种情况都会引起错误。有人能解释一下为什么会这样吗?我已经能够用g++和clang++来复制这个
编译标志的完整列表为-std=c++17 -g -Wall -Wextra -O3
,该错误由clang和gcc显示为-Werror
和-Wsign-compare
所致,而完整错误:comparison of integers of different signs: 'int' and 'unsigned long' [-Wsign-compare]
。
我们都是通过提供的g++ 9.3.1 20200408和clang++ 9.0.1获得这一点的。
最小工作示例:
#include <ctime>
#include <algorithm>
#include <cstdint>
#include <vector>
int main(void)
{
srand(static_cast<uint32_t>(time(0)));
std::vector<uint8_t> data(1024);
std::generate(std::begin(data), std::end(data), rand);
// No problem
for (size_t i = 0; i < data.size(); ++i)
{}
// No problem
for (int i = 0; i < data.size(); ++i)
{}
unsigned long x = data.size();
// Problem
for (int i = 0; i < x; ++i)
{}
return 0;
}
发布于 2020-07-02 07:22:44
我无法重现g++ 8.1.0的问题。如果我尝试将int (默认为签名)与size_t (默认为无签名)进行比较,则总是会收到错误/警告。这是预期的,因为int在默认情况下被定义为签名:https://de.cppreference.com/w/cpp/language/types。
当然,如果我使用一个类,它使用无符号的long作为大小类型,也会发生同样的情况。请参阅下面的示例和编译器输出:
#include <vector>
#include <iostream>
#include <initializer_list>
class MyClass{
public:
MyClass(){
}
MyClass(std::initializer_list<int> il): _size(std::distance(il.begin(), il.end())){
_vals = new int[_size];
std::copy(il.begin(), il.end(), _vals);
}
~MyClass(){
delete(_vals);
}
typedef unsigned long size_type ;
int& operator[](size_type index){
if (index >= _size) {
throw "Index out of range";
}
return _vals[index];
}
size_type size(){
return _size;
}
private:
int * _vals;
size_type _size;
};
int main() {
std::vector<int> collection = {1,2};
MyClass my_class = {3,4};
for(int i=0; i < collection.size(); i++){
std::cout << collection[i] << std::endl;
}
for(size_t i=0; i < collection.size(); i++){
std::cout << collection[i] << std::endl;
}
for(int i=0; i < my_class.size(); i++){
std::cout << my_class[i] << std::endl;
}
for(MyClass::size_type i=0; i < my_class.size(); i++){
std::cout << my_class[i] << std::endl;
}
return 0;
}
这将产生以下编译器输出:
# g++ -Wall .\main.cpp -o main
.\main.cpp: In function 'int main()':
.\main.cpp:41:18: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'unsigned int'} [-Wsign-compare]
for(int i=0; i < collection.size(); i++){
~~^~~~~~~~~~~~~~~~~~~
.\main.cpp:49:18: warning: comparison of integer expressions of different signedness: 'int' and 'MyClass::size_type' {aka 'long unsigned int'} [-Wsign-compare]
for(int i=0; i < my_class.size(); i++){
~~^~~~~~~~~~~~~~~~~
也许您正在编译没有的 -Wsign-compare
,而在第二个示例中,您正在用 -Wsign-compare
编译?也许您在第一个示例中使用-Wno-sign-compare
或-w
错误地禁用了警告?
发布于 2020-07-02 07:41:09
当您正在使用的实现将collection::size_type
定义为比std::size_t
更小的东西时,可能会出现这种情况。例如,如果将collection::size_type
定义为unsigned short
,将其与int
进行比较不会导致任何错误,而与std::size_t
(通常与指针的宽度至少相同)进行比较也不会导致任何错误,因为unsigned short
可以接受的每个值也可以用int
和std::size_t
表示。与pqxx::result::size_type
相比,unsigned long
将导致错误的出现,因为这种比较对int
不安全(但似乎对std::size_t
来说)。因此,可以这样做的一个例子是
// Pseudo code
typedef unsigned long std::size_t;
typedef unsigned short collection::size_type;
诚然,这是一个构造出来的例子,但仍然是可能的。不过,我只希望在嵌入式环境中出现这样的情况。
正如A.K.在另一个答案中所指出的,编译器标志也可能不同,这是IMHO更有可能的。
https://stackoverflow.com/questions/62689753
复制相似问题