Search code examples
c++linuxposixposix-api

Order of declarations in Posix structs -- is it guaranteed?


... or, in other words, is it safe to initialize system structures like this:

struct timespec ts[] = { {0, UTIME_OMIT}, {0, UTIME_OMIT} };
...
int r = utimensat(0, subPath.c_str(), ts, 0);

?


Solution

  • If you are relying only on POSIX, then no, it is not guaranteed that the initialization you present will have the effect you want. This is the extent of what it has to say about the definition of that structure type:

    The <time.h> header shall declare the timespec structure, which shall include at least the following members:

    time_t tv_sec Seconds.
    long tv_nsec Nanoseconds.

    It does not specify the relative order of those two members, nor does it specify that they be the first or only members, therefore it is not safe for your initializers to rely on member order.

    However, POSIX specifies C99 and incorporates it by reference, so you can use designated initializers to achieve about what you want:

    struct timespec ts[] = { { .tv_sec = 0, .tv_nsec = UTIME_OMIT},
                             { .tv_sec = 0, .tv_nsec = UTIME_OMIT} };
    

    Or, per @Storyteller's comment, C++20 catches up to C in that area if you want to write in that language. I confess, however, that until I looked more closely at the question's tags, I assumed C based on the use of this general style of initialization at all.