【问题标题】:Optimized away STL container's size优化了 STL 容器的大小
【发布时间】:2022-01-14 03:16:54
【问题描述】:

在调试问题时,我添加了一些tracepoints,将size()std::queue 打印为

The size of the queue is {mQueue.size()}

但我在“输出”窗口中看到此消息

The size of the queue is Function std::queue<Foo>::size has no address, possibly due to compiler optimizations.

如果我此时闯入代码,我确实会看到 size

mQueue
    c: { size=0 }
    [Raw View]: {c={ size=0 } }

但如果我再次尝试mQueue.size(),我会看到相同的日志

Function std::queue<Foo>::size has no address, possibly due to compiler optimizations.

有没有办法在跟踪点中获取size(),而不是通过更改代码来将大小存储在某个变量中并可能打印出来?我尝试包装在#pragma optimize( "", off ) 中添加跟踪点的函数,但无济于事。如果可能的话,我还想避免将链接器选项更改为/DEBUG:FULL

【问题讨论】:

    标签: c++ visual-studio


    【解决方案1】:

    编译器永远不需要为std::queue&lt;Foo&gt;::size() 生成代码,所以它不会打扰;所以在运行时,调试器没有它可以调用。

    一种解决方案是显式实例化函数,在源文件中使用 template std::queue&lt;int&gt;::size_type std::queue&lt;int&gt;::size() 之类的内容。但这需要您完全正确地声明,这会很痛苦,并且可能会使代码特定于编译器,甚至是特定于标准库的实现版本。

    另一种选择是在代码中的某处调用适当键入的size()。即使在从未调用过的代码中。

    例子:

    #include <queue>
    
    void thisIsNeverCalled()
    {
        std::queue<int> q;
        (void)q.size(); // If this line is present, the below tracepoint works
    }
    
    int main()
    {
        std::queue<int> q;
    
        for (int i = 0; i < 5; i++)
        {
            q.push(i); // can trace q.size() here if the above line is present
        }
    }
    

    (void) 只是用来消除来自[[nodiscard]] 属性的编译器警告。)

    请注意,这种方法不太可能在启用优化的情况下工作。为了缓解这种情况,用#pragma optimize 包围thisIsNeverCalled,并可能强制链接器用suitable #pragma comment 包含它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多