Skip to content

Unevaluated lambda in assert breaks gcc 7 build #705

Closed

Description

@chuckatkins
$ cmake ../../source/devel
-- The CXX compiler identification is GNU 7.1.1
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/chuckatkins/Code/nljson/build/devel
$ make
Scanning dependencies of target catch_main
[  2%] Building CXX object test/CMakeFiles/catch_main.dir/src/unit.cpp.o
[  2%] Built target catch_main
Scanning dependencies of target json_unit
[  5%] Building CXX object test/CMakeFiles/json_unit.dir/src/unit-algorithms.cpp.o
In file included from /usr/include/c++/7/cassert:44:0,
                 from /home/chuckatkins/Code/nljson/source/devel/src/json.hpp:34,
                 from /home/chuckatkins/Code/nljson/source/devel/test/src/unit-algorithms.cpp:31:
/home/chuckatkins/Code/nljson/source/devel/src/json.hpp: In constructor ‘nlohmann::detail::input_adapter::input_adapter(IteratorType, IteratorType)’:
/home/chuckatkins/Code/nljson/source/devel/src/json.hpp:1500:20: error: lambda-expression in unevaluated context
                    [&first](std::pair<bool, int> res, decltype(*first) val)
                    ^
make[2]: *** [test/CMakeFiles/json_unit.dir/build.make:63: test/CMakeFiles/json_unit.dir/src/unit-algorithms.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:88: test/CMakeFiles/json_unit.dir/all] Error 2
make: *** [Makefile:141: all] Error 2

Activity

  1. added a commit that references this issue on Aug 22, 2017
    7da0450
  2. nlohmann commented on Aug 22, 2017

    @nlohmann
    Owner

    It's odd I never experienced this error. What kind of compiler flags or Cmake options are you using?

  3. chuckatkins commented on Aug 22, 2017

    @chuckatkins
    ContributorAuthor

    Nothing special. I do tend to use a bleeding edge development build of CMake but that's it. No CFLAGS, or CXX flags, etc. This is a current Fedora 26 machine with my own CMake built from cmake/master and the system gcc 7.1.1. As you can see from the verbose output, no special flags are being passed.

    $ cmake --version
    cmake version 3.9.20170822-g8a0ed
    ...
    $ echo $CFLAGS $CXXFLAGS
    
    $ cmake ../../source/devel
    -- The CXX compiler identification is GNU 7.1.1
    -- Check for working CXX compiler: /usr/bin/c++
    -- Check for working CXX compiler: /usr/bin/c++ -- works
    -- Detecting CXX compiler ABI info
    -- Detecting CXX compiler ABI info - done
    -- Detecting CXX compile features
    -- Detecting CXX compile features - done
    -- Configuring done
    -- Generating done
    -- Build files have been written to: /home/chuckatkins/Code/nljson/build/devel
    $ make VERBOSE=1
    ...
    [  5%] Building CXX object test/CMakeFiles/json_unit.dir/src/unit-algorithms.cpp.o
    cd /home/chuckatkins/Code/nljson/build/devel/test && /usr/bin/c++   -I/home/chuckatkins/Code/nljson/source/devel/src -I/home/chuckatkins/Code/nljson/source/devel/test/src -I/home/chuckatkins/Code/nljson/source/devel/test/thirdparty/catch  -std=gnu++11 -o CMakeFiles/json_unit.dir/src/unit-algorithms.cpp.o -c /home/chuckatkins/Code/nljson/source/devel/test/src/unit-algorithms.cpp
    In file included from /usr/include/c++/7/cassert:44:0,
                     from /home/chuckatkins/Code/nljson/source/devel/src/json.hpp:34,
                     from /home/chuckatkins/Code/nljson/source/devel/test/src/unit-algorithms.cpp:31:
    /home/chuckatkins/Code/nljson/source/devel/src/json.hpp: In constructor ‘nlohmann::detail::input_adapter::input_adapter(IteratorType, IteratorType)’:
    /home/chuckatkins/Code/nljson/source/devel/src/json.hpp:1500:20: error: lambda-expression in unevaluated context
                        [&first](std::pair<bool, int> res, decltype(*first) val)
                        ^
    make[2]: *** [test/CMakeFiles/json_unit.dir/build.make:63: test/CMakeFiles/json_unit.dir/src/unit-algorithms.cpp.o] Error 1
    make[2]: Leaving directory '/home/chuckatkins/Code/nljson/build/devel'
    make[1]: *** [CMakeFiles/Makefile2:88: test/CMakeFiles/json_unit.dir/all] Error 2
    make[1]: Leaving directory '/home/chuckatkins/Code/nljson/build/devel'
    make: *** [Makefile:141: all] Error 2
    $ 
    

    FWIW, I believe it's likely an issue with compiler sensitivity since I didn't get this with gcc6 when I was running Fedora 24. I can reproduce this with a dummy example by putting a lamda inside an assert and evaluating it:

    // foo.cxx
    #include <cassert>
    int main(int argc, char **argv)
    { 
      assert([](int x) { return x == 0; }(argc));
      return 0;
    } 
    $ c++ -o foo -DDEBUG foo.cxx 
    In file included from /usr/include/c++/7/cassert:44:0,
                     from foo.cxx:1:
    foo.cxx: In function ‘int main(int, char**)’:
    foo.cxx:5:10: error: lambda-expression in unevaluated context
       assert([](int x) { return x == 0; }(argc));
              ^
    $ 
    
  4. theodelrieu commented on Aug 22, 2017

    @theodelrieu
    Contributor

    Isn't that a bug of GCC? I don't object to the fix, but it'd be great to report it if it's indeed a bug.

  5. chuckatkins commented on Aug 22, 2017

    @chuckatkins
    ContributorAuthor

    I thought so too at first but it's not. It has to do with how assert( foo ) is implemented and expanded by the preprocessor. The result of the preprocessor expansion of assert(foo) for a failing build is, amongst other things, an expression with sizeof( foo ) and per the C++ standard, the operand to sizeof( ... ) is an unevaluated expression. In turn, also per the C++ standard, lambda expressions are not allowed to appear in unevaluated expressions. After digging through the preprocessor output, I've been able to reproduce the error without the assert:

    int main(int argc, char **argv)
    {
      (void) sizeof( [] { return true; } () );
      return 0;
    }

    Which, indeed, is invalid because of the lambda expression being in the unevaluated operand of sizeof. The bug is not actually a gcc/g++ one but a glibc issue in that the implementation of assert() (I just figured this out btw) in assert.h which is incompatible with c++ lambda expressions. I tracked down the issue to a recent glibc commit which introduced the error by changing the assert implementation to use sizeofin order to squelch some pedantic warnings and another about two weeks later that subsequenty fixed it by not using sizeof for the implemention of assert when using C++. Unfortunately the first patch seems to have propagated to many distro's glibc releases while the later has not. So, I guess it's up to you as to whether or not to take #706 which I now realize is really a workaround for a glibc bug in Fedora 26, which is already patched upstream.

  6. theodelrieu commented on Aug 22, 2017

    @theodelrieu
    Contributor

    Wow, congrats for the impressive digging!

    Personally, I would not add a workaround to an already patched issue, but that is up to @nlohmann.

    Anyway, thanks a lot for your thorough research :)

  7. nlohmann commented on Aug 22, 2017

    @nlohmann
    Owner

    Thanks a lot for the research. I think merging the PR makes little sense here. If anyone encounters the same combination of problems, I think Google will send her/him here. :)

  8. added
    solution: invalidthe issue is not related to the library
    and removed on Aug 22, 2017
  9. markand commented on Aug 26, 2017

    @markand

    And I also was bitten by this bug as well :)

  10. vimpunk commented on Sep 4, 2018

    @vimpunk
    Contributor

    Has this been fixed? I'm unfortunately not on bleeding edge (xtensa gcc 5.2.0), and this error popped up on line 2165 in single_header/nlohmann/json.hpp. Would like to use this library as it looks really good, but can't currently due to this and I'd like to avoid forking it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    solution: invalidthe issue is not related to the library

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions