0

In the GNU's dd command's source code at github/dd.c,

There is a CPP(CPreProcessor) directive #define fdatasync(fd) (errno = ENOSYS, -1), which I understood correctly, but

Wherever I read on c programming forums, its mentioned that the sequence of expression evaluation, and return is un-defined in c, which means that in int i = 0; printf("%d, %d\n", i++, i++);, we cannot be sure, that the output would be 0, 1 or 1, 0

then how can gnu-dd programmers, be so surely, that -1 will be returned, and not errno,

thanks

gitman-2021
  • 111
  • 8
  • 1
    Don't confuse the argument list to a function with the comma operator. The argument list is evaluated in an unspecified order, the comma operator guarantees left-to-right evaluation. See the linked duplicate for details. – Lundin Mar 21 '23 at 07:51

1 Answers1

5

No, some sequences are undefined. The comma operator(a) is not one of those.

Appendix C of ISO C17 (latest iteration at the time of this question) lists the sequence points in C. These sequence points are defined such that all operations and side effects before the sequence point have (or act as if they have) completed fully before any of those after it begin.

One of those sequence points is given as:

Between the evaluations of the first and second operands of the following operators: logical AND && (6.5.13); logical OR || (6.5.14); comma , (6.5.17)


You should also note that, due to precedence rules (= is higher than ,), the expression errno = ENOSYS, -1 is effectively [errno = ENOSYS], [-1] rather than errno = [ENOSYS, -1], using [] to indicate the sub-expressions.

That means the sub-expression setting errno is done (with that sub-expression evaluating to ENOSYS(b)), then the complete expression ENOSYS, -1, has a result of -1.

It's the same as the difference between x = 1, 2 and x = (1, 2). The former sets x to one and the full expression gives two. The latter sets x to two because the result of 1, 2 is two and the parentheses have higher precedence than assignment.


(a) This is distinct from the comma when not used as an operator, such as when used to separate parameters to a function.


(b) This is what allows things like a = b = 42. Assignment has right-to-left associativity so it's effectively a = (b = 42).

So b is set to forty-two and the result of that assignment is that value, which is then assigned to a.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • 1
    C99 actually had this in normative text at 6.5 "Except as specified later (for the function-call (), &&, ||, ?:, and comma operators), the order of evaluation of subexpressions and the order in which side effects take place are both unspecified." Very poorly considered changes in C11 changed that to "Except as specified later", making the standard worse as a result. – Lundin Mar 21 '23 at 07:49