如果是enum,什么构成声明?

时间:2017-01-15 23:10:07

标签: c++ enums arduino embedded

编辑#1:添加最少的排斥,见下文:

背景

我正在尝试将我的代码细分为多个.cpp文件,所有这些文件都应该可以访问enum类型,我认为我在中声明头文件,然后包含在许多cpp个文件中。

但是,当我尝试将它们链接在一起时,我会遇到multiple definitionnot defined错误。我认为这源于我可能误解了声明是什么,以及定义是什么。我的意思是我很清楚(reference)

  • 当编译器为变量分配存储空间时定义变量。
  • 当编译器被告知存在变量时,声明变量(这是它的类型);它不会在那时为变量分配存储空间。

问题

如果我在main.h文件中有这个,这显然只是声明,不是吗?

#1

enum operation_status {
    PRE_START,
    RUNNING,
    PAUSED
};
那么这个怎么样?这是宣言还是定义?

#2

operation_status op_status;

我认为这确实是一个声明,并且它的定义将是

#3

op_status = PRE_START;

提前感谢您的回答!

可重复的例子:

Main.h

enum operation_status {
    PRE_START,
    RUNNING,
    PAUSED
};

//error given by this: 'multiple definition of op_status'
operation_status op_status;

//error given by this: 'undefined reference to op_status'
extern operation_status op_status;

void changeStatus();

Main.cpp的

#include <Arduino.h>
#include <main.h>

void setup() {
    op_status = PRE_START;
}

void loop() {
    ;
}

Change.cpp

#include <main.h>

void changeStatus() {
    op_status = RUNNING;
}

解决这个问题的最佳解决方案是什么?谢谢!

2 个答案:

答案 0 :(得分:3)

首先,每个定义都是一个声明;定义是一种特殊的声明。

enum operation_status {
    PRE_START,
    RUNNING,
    PAUSED
};

在技术上是一个定义 - 它定义了类型operation_status。但它是允许在多个编译单元中出现的排序的定义(只要它每次具有相同的内容和含义),因此头文件通常是它的正确位置。 / p>

operation_status op_status;

实际上是一个定义,即使它没有初始化器。要使其不是定义,您需要extern关键字:

extern operation_status op_status;

与之相关的定义属于一个源文件,并且可以选择具有初始化程序。

operation_status op_status = PRE_START;

最后,

op_status = PRE_START;

根本不是宣言。它是一个语句,仅在函数定义中有效。

答案 1 :(得分:1)

  

我正在尝试将我的代码分割成多个.cpp文件,所有这些文件应该可以访问枚举类型,我认为我在头文件中声明,然后包含在许多cpp文件中。

您无法转发声明没有指定基础类型的无范围枚举(标准不允许这样)。这是一种来自前c ++ 11时代的枚举。对于此类枚举,Standard不会对编译器强制执行任何默认的基础类型,因此如果您在枚举中仅指定了少量值,则可以使用char,或者如果您有一些大值,则可能使用short或int。但只有在你定义它时才会知道。

如果要声明未编组的枚举,则必须指定其基础类型。这是可能的,因为c ++ 11:

openjdk version "1.8.0_11" OpenJDK Runtime Environment (build 1.8.0_111-8u111-b14-2ubuntu0.16.04.2-b14) OpenJDK 64-Bit Server VM (build 25.111-b14-2ubuntu0.16.04.2-b14

但您也可以继续使用新的作用域枚举,默认情况下它们的基础类型是int:

// forward declare (in header file .h)
enum operation_status : int;


// define (in implementation file .cpp)
enum operation_status : int {
    PRE_START,
    RUNNING,
    PAUSED
};

[编辑]

您的问题:

// forward declare
enum class operation_status;


// define
enum class operation_status {
    PRE_START,
    RUNNING,
    PAUSED
};

这既是声明又是定义,我的上述答案对此更深入。

  

operation_status op_status;

那是定义。你不需要初始化它,使它成为一个定义。