【问题标题】:Compiler warning from std::chrono but is not being used来自 std::chrono 的编译器警告但未被使用
【发布时间】:2019-12-31 05:54:38
【问题描述】:

注意:此错误仅发生在 x64 项目的发布和调试模式中。

涉及std::chrono 的奇怪警告出现在使用 VC2019 的这段代码中,警告级别为 3。这是一段处理命令行标志的精简代码。我已经删除了大部分与问题无关的胆量。

#if 1   // enable bug
#include <chrono>   // excluding this also eliminates chrono warnings
using CorrectedIntType=int;
#else
using CorrectedIntType=size_t;
#endif

#include <iostream>
#include <vector>
#include <string>
#include <type_traits>

using std::vector;
using std::string;

namespace {
    void fixup(const std::string& argcmd, std::string& arg) { arg = argcmd; }

    template<class T>
    void procVal(std::vector<std::string>& arglist, CorrectedIntType idx, T& arg)
    {
        fixup(arglist[idx], arg);
        arglist.erase(arglist.begin() + idx);
    }

    template<class T, class ...TA>
    void procVal(std::vector<std::string>& arglist, CorrectedIntType idx, T& arg, TA&...argv)
    {
        procVal(arglist, idx, arg);
        procVal(arglist, idx, argv...);
    }

    template<class T, class ...TA>
    bool procFlag(const char* pc, std::vector<std::string>& arglist, T& arg1, TA&...argv)
    {
        std::string flag(pc);
        for (size_t i = 0; i < arglist.size(); i++)
        {
            if (arglist[i] == flag)
            {
                arglist.erase(arglist.begin() + i);
                procVal(arglist, i, arg1);      // process one argument after flag
                return true;
            }
        }
        return false;
    }
}

int main()
{
    string outfile;
    vector<string> test = { "test" };
    procFlag("-o", test, outfile);      // assigns test[0] to outfile and removes it
    std::cout << outfile << '\n';
}

警告:

1>Source.cpp
1>C:\Users\mgray\Documents\Visual Studio 2017\Projects\CommandLineCPP\stackoverflow\Source.cpp(35,1): warning C4267: 'argument': conversion from 'size_t' to 'CorrectedIntType', possible loss of data
1>C:\Users\mgray\Documents\Visual Studio 2017\Projects\CommandLineCPP\stackoverflow\Source.cpp(54): message : see reference to function template instantiation 'bool `anonymous-namespace'::procFlag<std::string,>(const char *,std::vector<std::string,std::allocator<std::string>> &,T &)' being compiled
1>        with
1>        [
1>            T=std::string
1>        ]
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.24.28314\include\chrono(632): message : see reference to class template instantiation 'std::chrono::duration<double,std::ratio<1,1>>' being compiled
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.24.28314\include\chrono(178): message : see reference to class template instantiation 'std::chrono::duration<__int64,std::nano>' being compiled
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Tools\MSVC\14.24.28314\include\chrono(610): message : see reference to class template instantiation 'std::chrono::time_point<std::chrono::steady_clock,std::chrono::nanoseconds>' being compiled

虽然代码有效,但即使出现合法警告的int -&lt;&gt; size_t 转换问题,当顶部的宏设置为 0 时,所有警告都会消失。因此,size_t 和 int 之间的大小差异会以某种方式触发计时消息。我担心chrono 警告存在,因为它不涉及。这是VS2019中的错误吗?关于为什么会出现 chrono 警告引用的任何想法?

【问题讨论】:

  • 您是否正在使用旧版本 VS 的 Windows SDK?如果是这样,那里的 STL 标头可能与您的 VS2019 项目的“严格性”和语言标准设置不兼容。
  • @AdrianMole 我正在使用最新的 SDK 并创建了一个新的解决方案来测试 sn-p,以防我进行了一些设置。但我会在另一台机器上的新安装中检查它。顺便说一句,x64 和 x86 编译中的错误相同。
  • 我在 W3 的 VS2019 中运行了您的代码,并在调试模式 x86 下打开了一致性模式,但我根本没有收到任何警告。如果你运行这个确切的例子,你会收到警告吗?我问是因为Source.cpp 的编译器警告与您所拥有的不匹配。它们指的是 1300 中的行,并且不匹配。
  • 最初的 real 警告是关于从 size_t 转换为 int 的精度损失。这些消息可能只是前一个问题可能发挥作用的后续行动('参见参考')。使用 size_t 作为更正类型,包含 chrono 也可能消除与 chrono 相关的消息。
  • @doug 您的警告显示Source.cpp(1343,1): warning C4267:,这意味着问题出在第 1343 行。没有第 1343 行,因此代码显示不能是这篇文章中的代码。

标签: c++ visual-studio compiler-warnings


【解决方案1】:

这是一个有效的警告,它与&lt;chrono&gt; 无关,但与您自己的代码和CorrectedIntType 类型有关。这是一个没有&lt;chrono&gt;的简化代码:https://gcc.godbolt.org/z/qf9v8TEh7

procVal的定义中,第二个参数是CorrectedIntType

void procVal(std::vector<std::string>& arglist, CorrectedIntType idx, T& arg)

但它是从procFlag 调用的,带有size_t 值:

bool procFlag(const char* pc, std::vector<std::string>& arglist, T& arg1)
    ...
    for (size_t i = 0; i < arglist.size(); i++)
    ...
            procVal(arglist, i, arg1);

因此,也可以通过将 i 类型更改为 CorrectedIntType 来修复警告。

【讨论】:

  • 谢谢。有趣的是它是如何出现的。模板错误混淆疯狂。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-04
  • 2012-06-22
  • 2023-03-14
相关资源
最近更新 更多