Question: I'm trying to get the OS and compiler name as a string in C++. Although there are many questions about this I did not find a definitive answer. So I tried to use Boost.Predef 1.55 which defines macros of the type `BOOST_OS_<OS>` and `BOOST_OS_<OS>_NAME`.

Hence one could simply do `if(BOOST_OS_<OS>) return BOOST_OS_<OS>_NAME;` for every OS boost supports. Same for compilers with `COMP` instead of `OS`. To avoid the repetition I wanted to use Boost.Preprocessor and put them all in a loop.

What I came up with is this:

```
#define MAKE_STMT_I2(PREFIX) if(PREFIX) return PREFIX ## _NAME;
#define MAKE_STMT_I(type, curName) MAKE_STMT_I2(BOOST_ ## type ## _ ## curName)
#define MAKE_STMT(s, type, curName) MAKE_STMT_I(type, curName)
#define OS_LIST (AIX)(AMIGAOS)(ANDROID)(BEOS)(BSD)(CYGWIN)(HPUX)(IRIX)(LINUX)(MACOS)(OS400)(QNX)(SOLARIS)(UNIX)(SVR4)(VMS)(WINDOWS)(BSDI)(DRAGONFLY)(BSD_FREE)(BSD_NET)(BSD_OPEN)

    BOOST_PP_SEQ_FOR_EACH(MAKE_STMT, OS, OS_LIST)

```

However I run into problems where the values are expanded to soon. E.g. VMS defines already a macro named `VMS` which then gets replaced in `OS_LIST`. Even doing something like `#define OS_LIST (##AIX##)(##AMIGAOS##)(...` does not help as it seems to get expanded in boost later.

How can I avoid the expansion in the sequence completely?

Answer: 
You defined `listofthings` as an empty C-style array (zero elements).

```
std::string listofthings[]
{
};

```

As [pointed by AndyG](https://stackoverflow.com/a/47435756/6022656), the language require that a size grather than zero, so your program is ill-formed. 

So, when you use it, 

```
listofthings[counter] = word;

```

the behavior is undefined and, in your case, the program crash.

Suggestion: transform `listofthings` in a `std::vector`

```
std::vector<std::string> listofthings;

```

and add elements using `emplace_back()` or `push_back()`

```
listofthings.emplace_back(std::move(word));

```

There is no need of `counter` and `listnr` (you can use `listofthings.size()`) and the print cycle become

```
for ( auto const & str : listofthings )
   std::cout << str << std::endl;

```
The statement 

```
std::string listofthings[]
{
};

```

Is ill-formed C++ because the language requires that the initializer for an array contain more than zero elements ([dcl.init.aggr]):

> 
> An array of unknown size initialized with a brace-enclosed initializer-list containing `n` *initializer-clauses*,
>  where `n` shall be greater than zero, is defined as having `n` elements.
> 
> 
> 

You just got unlucky because it appears you're using clang, which allows an extension for zero-sized arrays. (clang will warn if you have [`-Wpedantic`](http://clang.llvm.org/docs/DiagnosticsReference.html#wpedantic) or [`-Wzero-length-array`](http://clang.llvm.org/docs/DiagnosticsReference.html#wzero-length-array) turned on)

You should instead declare your array to have enough space for what you need, OR, [follow max66's advice and use a std::vector](https://stackoverflow.com/a/47435514/27678)