首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么:不同符号的整数比较有时只发生?

为什么:不同符号的整数比较有时只发生?
EN

Stack Overflow用户
提问于 2020-07-02 05:44:05
回答 2查看 3.3K关注 0票数 1

解决方案:检查是否有人安装了自定义编译器。

解决方案扩展:我只在服务器上编译,而不是在我的机器上本地编译,当我这样做时,我可以复制@A.K的答案。服务器上的编译是g++和clang++的经典版本。对不起,浪费了人们的时间:(编译器将是delte,我将安装一次官方文件。

这更多的是一个好奇的问题,而不是任何其他问题。当您比较数字类型时,让我们有时假设是intsize_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_typeunsigned longint 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获得这一点的。

最小工作示例:

代码语言:javascript
运行
复制
#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; 
}
EN

Stack Overflow用户

回答已采纳

发布于 2020-07-02 07:22:44

我无法重现g++ 8.1.0的问题。如果我尝试将int (默认为签名)与size_t (默认为无签名)进行比较,则总是会收到错误/警告。这是预期的,因为int在默认情况下被定义为签名:https://de.cppreference.com/w/cpp/language/types

当然,如果我使用一个类,它使用无符号的long作为大小类型,也会发生同样的情况。请参阅下面的示例和编译器输出:

代码语言:javascript
运行
复制
#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;
}

这将产生以下编译器输出:

代码语言:javascript
运行
复制
# 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错误地禁用了警告?

票数 2
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62689753

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档