Why does the named reference to an anonymous struct , idiom described below need -fms-extensions to be compiled by clang/gcc

StackOverflow https://stackoverflow.com/questions/20108938

  •  03-08-2022
  •  | 
  •  

Question

I wrote the following code to play with a specific C11 idiom of anonymous structs described in the book "21st Century C".

#include <stdio.h>
#include <math.h>


typedef struct Price {
  double close;
  double high;
  double low;
} Price;

typedef struct OLHC {
  union { //union allows the dual benefits of the seamless anon. struct and code-reuse
    struct Price;  //an anonymous struct but not explicitly re-defined
    Price p;
  };
  double open;
} OHLC;


double range(Price p){  //behaviour defined for struct Price
  return(p.high - p.low);
}

double travelRange(OHLC p){  //re-uses behaviour defined for struct Price
  return (fabs(p.open - p.low) + range(p.p) + fabs(p.high - p.close));
}

int main(){
  OHLC msft={.close=33.4,  //seamless access to members
         .open=32.1,
         .high=35.5,
         .low=30.23};
  printf("Today's travel Range for MSFT was %f\n",travelRange(msft));
}

I can get it to compile without warnings with either gcc48 or gcc49 as follows:

gcc-4.9  -std=c11 -fms-extensions -lm -o c11 c11.c

I can also get it to compile and run on my OS X mavericks macbook with one warning:

cc -std=c11 -fms-extensions -lm -o c11 c11.c

The warning is:

c11.c:19:5: warning: anonymous structs are a Microsoft extension[-Wmicrosoft]

Is there any version of gcc or clang which will compile this file with just the std=c11 flag without warnings. Are anonymous structs/unions part of C11 standard and just not implemented yet or are they as used above not conformant?

EDIT: Just to clarify the code above is designed to allow the reuse of code written for the base structure but at the same time get the benefits of the seamless access to all members of the derived structure containing the original structure anonymously. This is accomplished with the union of an anonymous struct and its corresponding named type. Too bad this is not conforming as I thought it was a really nice little idiom.

Was it helpful?

Solution

typedef struct OLHC {
  union {
    struct Price;
    Price p;
  };
  double open;
} OHLC;

is not C11. It is C with extensions and is only allowed in gcc with -fms-extensions option.

C11 has anonymous structures and unions but the:

    struct Price;

in you struct OLHC is not allowed as a part of C11 anonymous structures.

Is there any version of gcc or clang which will compile this file with just the std=c11 flag without warnings.

No, C requires at least a warning.

OTHER TIPS

To add to ouah's answer I re-worked the code to allow compilation with just the -std=c11 flag:

#include <stdio.h>
#include <math.h>        

typedef struct Price2 {
  double close;
  double high;
  double low;
} Price2;

typedef struct  {
  union {
    struct {  // Price2 equivalent textually re-defined within OLHC2
      double close;
      double high;
      double low;
    };
    Price2 p;
  };
  double open;
} OHLC2;


double range2(Price2 p){  //behaviour defined for struct Price2
  return(p.high - p.low);
}

double travelRange2(OHLC2 p){  //behaviour for struct Price2 re-used by OHLC2
  return (fabs(p.open - p.low) + range2(p.p) + fabs(p.high - p.close));
} 

int main(){

  OHLC2 msft2={.close=33.4,
         .open=32.1,
         .high=35.5,
         .low=30.23};
  printf("Today's travel Range for MSFT was %f\n",travelRange2(msft2));

}

The key unsatisfyingly is to replace the reference to the base structure in the derived structure by cutting and pasting the base struct definition sans tag and everything works. This seems to obviate some of the benefits of code re-use that works much better with the Microsoft extension switch.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top