Ошибка компилятора?На поведение лямбда-захвата влияет уровень оптимизации GCC - PullRequest
0 голосов
/ 28 ноября 2018
#include <functional>
#include <stdio.h>

int main()
{
    std::function<void(int)> func;
    int capture = 1234;

    printf("outside capture=%d\n", capture);

    if (capture) {
        func =
            [capture](int x) {
                printf("inside capture=%d\n", capture);
            };

        func(0);
    }
}

Скомпилируйте (с -Os, -O2 или -O3) и выполните его, результат будет

outside capture=1234
inside capture=67213

Скомпилируйте с -O1 или без -O ?, результат будет (вот чтоЯ ожидаю)

outside capture=1234
inside capture=1234

Что-то не так?Я сомневаюсь, что это ошибка компилятора или стандартной библиотеки C ++.Не могли бы вы дать мне несколько комментариев?

$ gcc-linaro-6.1.1-2016.08-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-g++ -v
Using built-in specs.
COLLECT_GCC=/opt/arm/gcc-linaro-6.1.1-2016.08-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-g++
COLLECT_LTO_WRAPPER=/opt/arm/gcc-linaro-6.1.1-2016.08-x86_64_arm-linux-gnueabihf/bin/../libexec/gcc/arm-linux-gnueabihf/6.1.1/lto-wrapper
Target: arm-linux-gnueabihf
Configured with: /home/tcwg-buildslave/workspace/tcwg-make-release/label/docker-trusty-amd64-tcwg/target/arm-linux-gnueabihf/snapshots/gcc-linaro-6.1-2016.08/configure SHELL=/bin/bash --with-mpc=/home/tcwg-buildslave/workspace/tcwg-make-release/label/docker-trusty-amd64-tcwg/target/arm-linux-gnueabihf/_build/builds/destdir/x86_64-unknown-linux-gnu --with-mpfr=/home/tcwg-buildslave/workspace/tcwg-make-release/label/docker-trusty-amd64-tcwg/target/arm-linux-gnueabihf/_build/builds/destdir/x86_64-unknown-linux-gnu --with-gmp=/home/tcwg-buildslave/workspace/tcwg-make-release/label/docker-trusty-amd64-tcwg/target/arm-linux-gnueabihf/_build/builds/destdir/x86_64-unknown-linux-gnu --with-gnu-as --with-gnu-ld --disable-libstdcxx-pch --disable-libmudflap --with-cloog=no --with-ppl=no --with-isl=no --disable-nls --enable-c99 --enable-gnu-indirect-function --with-tune=cortex-a9 --with-arch=armv7-a --with-fpu=vfpv3-d16 --with-float=hard --with-mode=thumb --disable-multilib --enable-multiarch --with-build-sysroot=/home/tcwg-buildslave/workspace/tcwg-make-release/label/docker-trusty-amd64-tcwg/target/arm-linux-gnueabihf/_build/sysroots/arm-linux-gnueabihf --enable-lto --enable-linker-build-id --enable-long-long --enable-shared --with-sysroot=/home/tcwg-buildslave/workspace/tcwg-make-release/label/docker-trusty-amd64-tcwg/target/arm-linux-gnueabihf/_build/builds/destdir/x86_64-unknown-linux-gnu/arm-linux-gnueabihf/libc --enable-languages=c,c++,fortran,lto --enable-checking=release --disable-bootstrap --build=x86_64-unknown-linux-gnu --host=x86_64-unknown-linux-gnu --target=arm-linux-gnueabihf --prefix=/home/tcwg-buildslave/workspace/tcwg-make-release/label/docker-trusty-amd64-tcwg/target/arm-linux-gnueabihf/_build/builds/destdir/x86_64-unknown-linux-gnu
Thread model: posix
gcc version 6.1.1 20160711 (Linaro GCC 6.1-2016.08) 

Эта проблема также может быть проверена на x86_64 с помощью следующих команд оболочки

sudo apt-get -y install qemu-user

wget https://releases.linaro.org/components/toolchain/binaries/6.1-2016.08/arm-linux-gnueabihf/gcc-linaro-6.1.1-2016.08-x86_64_arm-linux-gnueabihf.tar.xz
tar -xf gcc-linaro-6.1.1-2016.08-x86_64_arm-linux-gnueabihf.tar.xz

cat <<EOF > test.cpp
#include <functional>
#include <stdio.h>

int main()
{
    std::function<void(int)> func;
    int capture = 1234;

    printf("outside capture=%d\n", capture);

    if (capture) {
        func =
            [capture](int x) {
                printf("inside capture=%d\n", capture);
            };

        func(0);
    }
}
EOF

gcc-linaro-6.1.1-2016.08-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-g++ -Os test.cpp

qemu-arm gcc-linaro-6.1.1-2016.08-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc/lib/ld-linux-armhf.so.3 --library-path gcc-linaro-6.1.1-2016.08-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc/lib ./a.out

Результат -

outside capture=1234
inside capture=-161318064
...