为什么对匿名结构的命名引用,下面描述的习惯用法需要-cms-extensions由clang / gcc编译

时间:2013-11-20 23:00:08

标签: c c11

我编写了以下代码,以使用“21世纪C”一书中描述的匿名结构特定C11成语

#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));
}

我可以使用gcc48或gcc49进行编译而不发出警告,如下所示:

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

我也可以通过一个警告来编译并运行我的OS X mavericks macbook:

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

警告是:

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

是否有任何版本的gcc或clang将使用std = c11标志编译此文件而不发出警告。匿名结构/联合是C11标准的一部分,还没有实现,或者它们是否与上面使用的不一致?

编辑:只是为了澄清上面的代码,旨在允许重用为基础结构编写的代码,但同时获得匿名包含原始结构的派生结构的所有成员的无缝访问的好处。这是通过匿名结构及其相应的命名类型的并集来实现的。太糟糕了,这不符合我认为这是一个非常好的小成语。

2 个答案:

答案 0 :(得分:3)

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

不是C11。它是带扩展名的C,只允许gcc使用-fms-extensions选项。

C11有匿名结构和联合,但是:

    struct Price;
struct OLHC中的

不允许作为C11匿名结构的一部分。

  

是否有任何版本的gcc或clang将使用std = c11标志编译此文件而不发出警告。

不,C至少需要警告。

答案 1 :(得分:2)

要添加到ouah的答案,我重新编写代码以允许仅使用-std = c11标志进行编译:

#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));

}

关键是不满意的是通过剪切和粘贴基础结构定义sans标签来替换派生结构中对基础结构的引用,一切正常。这似乎消除了一些代码重用的好处,使用Microsoft扩展交换机可以更好地工作。