2

I'm not sure whether this is an actual bug of the LLVM that comes with Xcode 4.6.3 (4H1503) or if I'm doing something really not kosher. The snippet of code is as follows

for(auto &a : matrix[j]) {
    a = false;
}

where matrix is a vector of vectors containing booleans. I've been developing with Visual Studio 2012 for a while and this didn't seem to be a problem, but then the application needs to run on a Mac as well so I went on and tested it... and I was a bit surprised that I couldn't get it to compile. Upon closer inspection, I've discovered that I was getting a full blown segfault from clang itself, which is usually indication of very bad shenanigans going on. So I quickly isolated the piece of code and changed the loop to a more peasant's version using an integer index and all that jazz. It works like a charm.

Am I correct in assuming that my original loop was supposed to be working (I've seen similar things even here in SO, and besides VS2012 didn't have anything to say, really) or am I making a gross mistake and you are really not supposed to use references like that?

I'd like to know this before reporting the bug to Apple.

EDIT

#include <vector>

using namespace std;

int main(void) {
    vector<vector<bool>> matrix = vector<vector<bool>>(10, vector<bool>(5, false));;

    for(auto &a : matrix[0]) {
        a = true;
    }

    return 0;
}

compiling with clang -x c++ -std=c++11 -stdlib=libc++ yields

0  clang 0x0000000100c57bb2 main + 12932498
Stack dump:
0.  Program arguments: /usr/bin/clang -cc1 -triple x86_64-apple-macosx10.8.0 -emit-obj -mrelax-all -disable-free -disable-llvm-verifier -main-file-name rbloop.cpp -pic-level 2 -mdisable-fp-elim -masm-verbose -munwind-tables -target-cpu core2 -target-linker-version 136 -resource-dir /usr/bin/../lib/clang/4.2 -fmodule-cache-path /var/folders/ny/y4mgzkq14db49kfh7rnvcnshqvrkjz/T/clang-module-cache -stdlib=libc++ -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /Users/af6539/src -ferror-limit 19 -fmessage-length 120 -stack-protector 1 -mstackrealign -fblocks -fobjc-runtime=macosx-10.8.0 -fobjc-dispatch-method=mixed -fobjc-default-synthesize-properties -fcxx-exceptions -fexceptions -fdiagnostics-show-option -fcolor-diagnostics -o /var/folders/ny/y4mgzkq14db49kfh7rnvcnshqvrkjz/T/rbloop-AUzjp6.o -x c++ rbloop.cpp 
1.  rbloop.cpp:9:22: current parser token '{'
2.  rbloop.cpp:6:16: parsing function body 'main'
3.  rbloop.cpp:6:16: in compound statement ('{}')
clang: error: unable to execute command: Segmentation fault: 11
clang: error: clang frontend command failed due to signal (use -v to see invocation)
Apple LLVM version 4.2 (clang-425.0.28) (based on LLVM 3.2svn)
Target: x86_64-apple-darwin12.4.0
Thread model: posix
clang: note: diagnostic msg: PLEASE submit a bug report to http://developer.apple.com/bugreporter/ and include the crash backtrace, preprocessed source, and associated run script.
clang: note: diagnostic msg: 
********************

PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:
Preprocessed source(s) and associated run script(s) are located at:
clang: note: diagnostic msg: /var/folders/ny/y4mgzkq14db49kfh7rnvcnshqvrkjz/T/rbloop-HcbryW.cpp
clang: note: diagnostic msg: /var/folders/ny/y4mgzkq14db49kfh7rnvcnshqvrkjz/T/rbloop-HcbryW.sh
clang: note: diagnostic msg: 

********************

I'm not pasting the files mentioned at the end because they are ridiculously large and don't seem to add any information (just a bunch of library headers and then my exact code as above pasted at the end of the file). Besides, if you had the same compiler I have, you should be able to get them yourselves.

Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
Morpheu5
  • 2,610
  • 6
  • 39
  • 72
  • A more complete example is needed. We do not see what your `matrix` really is, nor what `j` is. If `matrix` is `vector>` then `matrix[j]`, assuming valid index, would be `vector`. How do you intend to assign `false` to a `vector`? – DUman Jul 31 '13 at 13:42
  • @ShafikYaghmour, done, hope it helps. @user1264727: yes, `matrix[j]`, assuming the right index (which is) is a vector of booleans. You pass a container to a range-based loop and get every element in the container inside the loop, in this case my auto &a would be a reference to a bool, and that's how I intend to assign a bool literal to a bool variable. Read up on range-based loops :) – Morpheu5 Jul 31 '13 at 14:57

2 Answers2

5

Having your compiler dump a stack trace on you is always a bug in the compiler. If the compiler doesn't like your code, it should give you a decent error message, not a stack trace of its internals.

With your example code I would expect a diagnostic along the lines of:

test.cpp:8:15: error: non-const lvalue reference to type '__bit_reference<[2 * ...]>' cannot bind to a temporary of type
      '__bit_reference<[2 * ...]>'
    for(auto &a : matrix[0]) {
              ^ ~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/vector:2127:14: note: 
      selected 'begin' function with iterator type 'iterator' (aka '__bit_iterator<std::__1::vector<bool,
      std::__1::allocator<bool> >, false>')
    iterator begin() _NOEXCEPT
             ^
1 error generated.
Howard Hinnant
  • 206,506
  • 52
  • 449
  • 577
  • Interesting. So I should go ahead and report the bug, you say? Besides, which version of which compiler did you use to get that diagnostic? As I said, even my test code compiles and runs fine with VS2012. – Morpheu5 Jul 31 '13 at 15:05
  • @Morpheu5 There are many online C++ compilers to make it a little easier, `g++` gives you a similar warning: http://stackoverflow.com/questions/3916000/online-c-compiler-and-evaluator – Shafik Yaghmour Jul 31 '13 at 15:06
  • Wow, thanks! I didn't even know such a thing existed. Online C++ compilers, now that's handy :) – Morpheu5 Jul 31 '13 at 15:09
  • @Morpheu5 I don't think you need to report this as it appears to already be fixed on newer versions of clang. – bames53 Jul 31 '13 at 17:56
3

As Howard says, the compiler should not give you a stack trace but produce an error message and as you can see gcc does produce a good diagnostic. The reason that you receive an error is that std::vector<bool> is a specialization and this thread gives some good details. So at least in gcc and clang what you get back is a proxy that acts as a reference but since it is a temporary object you can not take a reference to it and you don't need to since changes will be reflected back, I am not sure about visual studio though. This example demonstrates what I mean.

Community
  • 1
  • 1
Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
  • I wish I could accept both answers. I'm accepting this because of the links, but Howard's was immensely helpful as well. – Morpheu5 Jul 31 '13 at 15:49