Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Side effects in generic expressions

Tags:

I'm doing some experiments with the new _Generic keyword and stumbled upon a special case regarding multiple evaluations. See the following:

#include <stdio.h>  #define write_char(c) _Generic(c, char: putchar, const char: putchar)(c)  int main(void) {     const char *s = "foo";      write_char(*s++);     write_char(*s++);     write_char(*s++);      putchar('\n'); } 

This compiles fine and produces the expected result with GCC:

$ gcc -std=c11 -Wall plusplus.c -o plusplus $ ./plusplus  foo 

On the other hand, Clang outputs a big honking warning:

$ clang -std=c11 plusplus.c -o plusplus plusplus.c:9:18: warning: multiple unsequenced modifications to 's'       [-Wunsequenced]     write_char(*s++);                  ^~ plusplus.c:3:32: note: expanded from macro 'write_char' #define write_char(c) _Generic(c, char: putchar, const char: putchar)(c)  ... 

Yet the result is as expected:

$ ./plusplus foo 

I checked the draft of the standard, which says (at p. 97 of the PDF):

The controlling expression of a generic selection is not evaluated.

This seems to precisely address the problem of side-effects in macros (e.g., MIN and MAX).

Now, can I safely ignore Clang's warning, or am I wrong?

like image 827
michaelmeyer Avatar asked Dec 20 '14 20:12

michaelmeyer


People also ask

Do generic medicines have more side effects?

Generic medicines use the same active ingredients as brand-name medicines and work the same way, so they have the same risks and benefits as the brand-name medicines.

Do different generic brands have different side effects?

Myth 4: Generic medications are more likely to cause side effects. The FDA requires that generics have the same clinical risks and benefits as their brand-name counterparts, so one version shouldn't cause more side effects than the other should.

Is generic medicine good for health?

Generic medicines work the same as brand-name medicines A generic medicine is required to be the same as a brand-name medicine in dosage, safety, effectiveness, strength, stability, and quality, as well as in the way it is taken. Generic medicines also have the same risks and benefits as their brand-name counterparts.

How do you explain side effects?

In medicine, a side effect is an effect, whether therapeutic or adverse, that is secondary to the one intended; although the term is predominantly employed to describe adverse effects, it can also apply to beneficial, but unintended, consequences of the use of a drug.


1 Answers

As I mentioned in comments, you posted the question about two weeks after the bug was fixed in Clangs trunk. See revision rL223266 (December 3 2014). The fix is included in Clang 3.6.

Now, can I safely ignore Clang's warning, or am I wrong?

We already know that you're right, so here is a way to ignore pragmas in Clang for the future:

#pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunsequenced"  write_char(*s++);  #pragma clang diagnostic pop 

To do not repeat it on every use of the macro, you could put _Pragma in its body:

#define write_char(c) \     _Pragma("clang diagnostic push") \     _Pragma("clang diagnostic ignored \"-Wunsequenced\"") \     _Generic(c, char: putchar, const char: putchar)(c) \     _Pragma("clang diagnostic pop") 
like image 68
xaizek Avatar answered Sep 22 '22 04:09

xaizek