【问题标题】:Code Fragment: is this pure C?代码片段:这是纯 C 吗?
【发布时间】:2012-12-01 07:23:08
【问题描述】:

我有以下代码片段,我想知道它是纯 C 还是包含一些 C++ 元素。这个问题源于我认为它只是C,但是一些编译器不接受代码。

   // User struct derived from FunctionBlock
    struct Function{
        // Inputs
        int codeGenerationIterator;
        int i;
        char* s;
        // Outputs
        // Internal
    };
    void FunctionCall(struct Function *arg){
    }
    void FunctionConstructor(struct Function *arg){
        arg->i=3;
        arg->s="!";
        // Call constructor for all not primitive variables
        // Create struct with first call
        FunctionCall(arg);
    }
    // User type definition
    typedef struct Punto{
        int codeGenerationIterator;
        Function x[3+1];
            Function *x_pointer[3+1];
        double y;
    };
    void PuntoConstructor(struct Punto *arg){
        // Call constructor for all not primitive variables
        for(arg->codeGenerationIterator=0;arg->codeGenerationIterator<=3;arg->codeGenerationIterator++){
            arg->x_pointer[arg->codeGenerationIterator]=&(arg->x[arg->codeGenerationIterator]);
            FunctionConstructor(arg->x_pointer[arg->codeGenerationIterator]);
        }
    }
    // User type definition
    typedef struct Cerchio{
        int codeGenerationIterator;
        double r;
        Punto centro;
            Punto *centro_pointer;
    };
    void CerchioConstructor(struct Cerchio *arg){
        // Call constructor for all not primitive variables
            arg->centro_pointer=&(arg->centro);
        PuntoConstructor(arg->centro_pointer);
    }
    // User type definition
    typedef struct Container{
        int codeGenerationIterator;
        Cerchio circonferenza[10+1];
            Cerchio *circonferenza_pointer[10+1];
    };
    void ContainerConstructor(struct Container *arg){
        // Call constructor for all not primitive variables
        for(arg->codeGenerationIterator=0;arg->codeGenerationIterator<=10;arg->codeGenerationIterator++){
            arg->circonferenza_pointer[arg->codeGenerationIterator]=&(arg->circonferenza[arg->codeGenerationIterator]);
            CerchioConstructor(arg->circonferenza_pointer[arg->codeGenerationIterator]);
        }
    }

    int main(void){

        // Variable definitions
        int codeGenerationIterator;
        int count;
        Punto insiemePunti[50+1];
            Punto *insiemePunti_pointer[50+1];
        Cerchio cerchio;
            Cerchio *cerchio_pointer;
        Container container;
            Container *container_pointer;
        Container containers[11+1];
            Container *containers_pointer[11+1];
        // Call constructor for all not primitive variables
        for(codeGenerationIterator=0;codeGenerationIterator<=50;codeGenerationIterator++){
            insiemePunti_pointer[codeGenerationIterator]=&insiemePunti[codeGenerationIterator];
            PuntoConstructor(insiemePunti_pointer[codeGenerationIterator]);
        }
            cerchio_pointer=&cerchio;
        CerchioConstructor(cerchio_pointer);
            container_pointer=&container;
        ContainerConstructor(container_pointer);
        for(codeGenerationIterator=0;codeGenerationIterator<=11;codeGenerationIterator++){
            containers_pointer[codeGenerationIterator]=&containers[codeGenerationIterator];
            ContainerConstructor(containers_pointer[codeGenerationIterator]);
        }

        container.circonferenza[1].centro.x[0].i=2;
        containers[2].circonferenza[2].centro.x[4].i=2;

    printf("Works!");
    getchar();getchar(); // TODO: delete
    return 0;
    }

如您所见,我没有使用类或重载,而只使用了简单的指令、结构和一些指针。那么,为什么一些严格的 C 编译器会给我一个错误呢?

【问题讨论】:

  • 错误信息是什么?
  • 你得到什么错误以及来自哪个编译器?
  • 编译器的一些例子是:“Miracle C”、“Tiny C”,并且错误没有提供任何信息(类似于“missing ';' at...)
  • something like "missing ';' at... 正是您找到错误所需的信息

标签: c compiler-construction strict


【解决方案1】:

不,这是无效的 C。这一行:

    Function x[3+1];

缺少struct 关键字,也没有typedef struct Function Function; 来介绍您似乎正在使用的类型别名。

另外,// cmets 的使用需要足够新的编译器,该语法直到 C99 才正式添加到 C 中。旧的编译器也会因为这个原因而失败。

【讨论】:

  • 好吧,你可以说它是非编译的 C 语言,它只缺少一些 struct 关键字? :P
  • 所以我只需要在变量定义之前添加struct关键字?
  • @TommasoDS 最好的方法是使用typedef struct {} Function;,因为这样你就会得到一个与 C++ 兼容的类型命名系统。有些人喜欢输入 struct,原因不明。 (例如,Linux 内核编码标准包含一个相当模糊的理由,即为什么到处都写 struct 会很好。)
  • @Lundin 命名结构是创建自引用数据结构和前向声明所必需的。此外,在gdb 中检查时,无名结构看起来很丑。
  • @Lundin 但在这种情况下,您还命名了该结构。
【解决方案2】:

Some example of compilers are: "Miracle C", "Tiny C" and the error does not provide any information

也许尝试一个真正的编译器呢?不如直接把你的代码扔到 GCC 中以获得更好的错误消息。

尽管如此,听起来您收到错误消息:"missing ';' at 可能只是意味着编译器看起来应该是两个语句,而您忘记用; 将其分解,它可能不会是 best 错误消息,但没有编译器可以总能直接告诉你哪里出了问题,它们只是提示,因为它们希望你更聪明。 :)

你的代码中有一堆structs:

typedef struct Cerchio {
typedef struct Punto {
struct Function{

其中一个structs 与其他人不同。

  • 如果您使用typedef,您可以仅通过名称Cerchio 来引用结构(例如)。
  • 如果你不使用typedef,你需要每次显式调用它:struct Function

【讨论】:

    【解决方案3】:

    除了缺少struct 关键字外,您的代码还必须#include &lt;stdio.h&gt;。在 C99 中,这是一个格式良好的程序所必需的。在 C89 中,没有它的程序是格式良好的(一旦其他错误得到修复),但具有未定义的行为。

    gcc -pedantic-errors -std=c99 将为您提供包含错误的确切行号,此外还会提供一些您应该注意的警告。您的定义如下:

    typedef struct Punto { ... };
    

    都是错误的,即使它们是合法的。 typedef 无效,因为您没有为您应该定义的类型提供名称。因此,在 C 中识别它的唯一方法是 struct Punto,而不是您想要的 Punto,因为它可以在 C++ 中识别。

    【讨论】:

    • 有包含,我没有报告。
    猜你喜欢
    • 1970-01-01
    • 2012-10-24
    • 2011-05-24
    • 2017-10-04
    • 1970-01-01
    • 1970-01-01
    • 2017-03-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多