g++ osx 上使用 -O3 的优化错误

发布于 2024-12-18 10:24:00 字数 1682 浏览 4 评论 0原文

使用 -O3 编译时,以下代码会生成错误的退出代码。我认为内部循环被错误地优化掉了。使用 -O2 或 -fno-inline 它可以工作。生成一个更简单的示例很困难,因为任何小的更改和错误都会消失。

编译:

/usr/bin/g++ -O3 -o bugexample bugexample.cpp

代码:

#include <vector>

int test(std::vector<char>& a, int& b)
{
    std::vector<int> z;
    z.push_back(10);
    z.push_back(10);

    int d = (int)a.size();

    int x = 1;
    for (int j = 0; j < 2; j++)
    {
        int c = j - 1;

        for (int i = 0; i < d; i++) 
        {
            if (j == 0)
            {
            }
            else if (i == 0)
            {
            }
            else
            {
                if (a[j] == a[i - 1])
                {
                    b = c + 1;
                    x = 2;
                }
                z[i] = 1;
            }
        }
    }

    return x;
}


int main(int argc, char* argv[])
{
    std::vector<char> a;
    a.push_back('a');
    a.push_back('a');
    int b = 1;
    return test(a,b);
}

编译器版本:

/usr/bin/g++ -v
Using built-in specs.
Target: i686-apple-darwin10
Configured with: /var/tmp/gcc/gcc-5666.3~123/src/configure --disable-checking --enable-werror --prefix=/usr --mandir=/share/man --enable-languages=c,objc,c++,obj-c++ --program-transform-name=/^[cg][^.-]*$/s/$/-4.2/ --with-slibdir=/usr/lib --build=i686-apple-darwin10 --program-prefix=i686-apple-darwin10- --host=x86_64-apple-darwin10 --target=i686-apple-darwin10 --with-gxx-include-dir=/include/c++/4.2.1
Thread model: posix
gcc version 4.2.1 (Apple Inc. build 5666) (dot 3)

对任何 insite 感兴趣,或者证明这是我的错。

编辑:生成的退出代码是 1,而它应该是 2。

The following code produces the wrong exit code when compiled with -O3. I think the inner loop is being optimized away incorrectly. With -O2 or -fno-inline it works. Producing a simpler example is difficult because any small changes and the bug disappears.

Compiled with:

/usr/bin/g++ -O3 -o bugexample bugexample.cpp

Code:

#include <vector>

int test(std::vector<char>& a, int& b)
{
    std::vector<int> z;
    z.push_back(10);
    z.push_back(10);

    int d = (int)a.size();

    int x = 1;
    for (int j = 0; j < 2; j++)
    {
        int c = j - 1;

        for (int i = 0; i < d; i++) 
        {
            if (j == 0)
            {
            }
            else if (i == 0)
            {
            }
            else
            {
                if (a[j] == a[i - 1])
                {
                    b = c + 1;
                    x = 2;
                }
                z[i] = 1;
            }
        }
    }

    return x;
}


int main(int argc, char* argv[])
{
    std::vector<char> a;
    a.push_back('a');
    a.push_back('a');
    int b = 1;
    return test(a,b);
}

Compiler version:

/usr/bin/g++ -v
Using built-in specs.
Target: i686-apple-darwin10
Configured with: /var/tmp/gcc/gcc-5666.3~123/src/configure --disable-checking --enable-werror --prefix=/usr --mandir=/share/man --enable-languages=c,objc,c++,obj-c++ --program-transform-name=/^[cg][^.-]*$/s/$/-4.2/ --with-slibdir=/usr/lib --build=i686-apple-darwin10 --program-prefix=i686-apple-darwin10- --host=x86_64-apple-darwin10 --target=i686-apple-darwin10 --with-gxx-include-dir=/include/c++/4.2.1
Thread model: posix
gcc version 4.2.1 (Apple Inc. build 5666) (dot 3)

Interested in any insite, or proof that its my fault.

Edit: The exit code produced is 1, whereas it should b 2.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

作妖 2024-12-25 10:24:00

嗯,这是某种混淆代码竞赛吗?

据我所知,您正在尝试对输入向量进行某种回文测试。只是,

  • 循环 var j 的硬编码上限为 2 (这可能也应该是 a.size() ?),
  • 您只返回最后一个位置的检查
  • 你有各种各样的冗余条件
  • 你有无偿的非常量参数
  • 你有未使用的z向量
  • 你不必要地使用了int for bool(1 =&gt; false - 未找到,2 =&gt; true -发现)
  • 你不必要地使用了输出参数b;我将 bool 返回类型替换为 b 的值(b==-1 表示未找到匹配项)

在简化这些内容的代码时,我得到了以下代码,并且(就像您自己的代码一样)它对于 g++ 4.6.1 上的所有优化级别的行为都是相同的:

#include <vector>

int test(const std::vector<char>& a)
{
    /* int j = 1; // was: for (int j = 1; j < 2; j++) */

    for (int i = a.size()-1; i > 1; i--) 
        if (a[1] == a[i - 1])
            return 1;

    return -1;
}


int main(int argc, char* argv[])
{
    std::vector<char> a(2, 'a');
    int b = test(a);

    return b==-1? 1 : 2;
}

Mmm is this some kind of obfuscated code contest?

As far as I can tell you're trying to do some kind of palindrome test on the input vector. Only,

  • the loop var j has a hardcoded upperbound of 2 (which should probably have been a.size() as well?)
  • you only return the check of the last position
  • you had all kinds of redundant conditions
  • you had gratuitous non-const arguments
  • you had unused z vector
  • you had unnecessary use of int for bool (1=>false - not found, 2=>true - found)
  • you had unnecessary use of out parameter b; I replaced that bool return type with the value of b (with b==-1 indicating no match found)

When simplifying the code for these things, I get this code, and (like your own code) it behaves identically for all optimization levels on g++ 4.6.1:

#include <vector>

int test(const std::vector<char>& a)
{
    /* int j = 1; // was: for (int j = 1; j < 2; j++) */

    for (int i = a.size()-1; i > 1; i--) 
        if (a[1] == a[i - 1])
            return 1;

    return -1;
}


int main(int argc, char* argv[])
{
    std::vector<char> a(2, 'a');
    int b = test(a);

    return b==-1? 1 : 2;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文