Petr Skocik
Petr Skocik

Reputation: 60107

Initializing a global, const POD struct; addressing specific members

http://pubs.opengroup.org/onlinepubs/007908799/xsh/time.h.html says that

The header declares the structure timespec, which has at least the following members: time_t tv_sec seconds long tv_nsec nanoseconds

I'm working with this in C++, and I would like to do the following:

//global scope
const /*struct*/ timespec ARMAGEDDON = {
    .tv_sec = std::numeric_limits<decltype((timespec().tv_sec))>::max(), 
    .tv_nsec = std::numeric_limits<decltype((timespec().tv_nsec))>::max(), 
};

While C++ allows me to rather flexibly get the maximums of the respective struct members (unlike plain C, as far as I know), I can't use the .member = value, C syntax to address the particular members I want.

const /*struct*/ timespec ARMAGEDDON = {
      std::numeric_limits<decltype((timespec().tv_sec))>::max(), 
      std::numeric_limits<decltype((timespec().tv_nsec))>::max(), 
};

happens to compile, but AFAIK, this initializes the first two members. The API provider doesn't say .tv_sec and .tv_nsec are the first two members.

What is the correct way to initialize the struct in C++?

Upvotes: 1

Views: 185

Answers (2)

gwiazdorrr
gwiazdorrr

Reputation: 6339

If you don't want to clutter your global namespace and want to have something resembling C-style initialisation, you can always construct and object using lambda expression.

const timespec ARMAGEDDON = []() -> timespec {
    timespec result;
    result.tv_sec = std::numeric_limits<decltype(result.tv_sec)>::max();
    result.tv_nsec = std::numeric_limits<decltype(result.tv_nsec)>::max();
    return result;
}();

EDIT: If your compiler is fairly up to date, you should be able to use a slightly shorter construct:

const timespec ARMAGEDDON = [](){
    timespec result;
    result.tv_sec = std::numeric_limits<decltype(result.tv_sec)>::max();
    result.tv_nsec = std::numeric_limits<decltype(result.tv_nsec)>::max();
    return result;
}();

Upvotes: 2

Barry
Barry

Reputation: 303457

What's wrong with:

timespec ARMAGEDDON;
ARMAGEDDON.tv_sec = ...;
ARMAGEDDON.tv_nsec = ...;

If you really want it to be const, you can move that into a function:

timespec makeArmageddon() {
    timespec ts;
    ts.tv_sec = ...;
    ts.tv_nsec = ...;
    return ts;
}

const timespec ARMAGEDDON = makeArmageddon();

Since the API just says it has at least those members, without even specifying that they are the first two members, I'd just as soon avoid aggregate initialization. Yes, designated initializers would be great here - but I'd still rather be writing C++.

Upvotes: 2

Related Questions