Почему вы не можете определить членов структуры глобально? - PullRequest
2 голосов
/ 16 июня 2019

Когда вы определяете struct глобально, почему вы не можете определить глобальные элементы структуры также (вне использования синтаксиса инициализатора)? Ошибка, которую я получаю от clang, состоит в том, что system_1 имеет «неизвестное имя типа».

Если вы определите структуру внутри функции, например, main(), то у вас не возникнет никаких проблем.

typedef struct Light_System {
    int redLightPin;
    int yellowLightPin;
    int blueLightPin;
} Light_System;

Light_System system_1;

# "Light_System system_1 = {4, 0, 0}" works

system_1.redLightPin = 4; # doesn't work

int main(int argc, char *argv[]) {
    # placing everything in here works
    # placing just "system_1.redLightPin = 4;" here makes it work.
    printf("%d\n", system_1.redLightPin);
    return 0;
}

Я ожидаю, что смогу определить членов структуры в глобальной области видимости.

Ответы [ 3 ]

5 голосов
/ 16 июня 2019

Когда вы определяете структуру глобально, почему вы не можете определить элементы структуры глобально (вне использования синтаксиса инициализатора)?

Потому что вы пытаетесь сделать этоне определение или инициализация .Это назначение .Вы можете объявлять, определять и инициализировать в глобальной области видимости, но не назначать.

Это не только для структур.Это относится и к переменным.Вне функции вы можете только объявить и инициализировать переменные.Вы не можете выполнять регулярные задания или что-либо еще по этому вопросу.Я не уверен на 100% в деталях, но я вполне уверен, что вы не можете сделать ничего в глобальной области видимости, чего нельзя сделать во время компиляции.

Так что это будет работать:

int x=5;

Но не это:

int x;
x = 5;

Ну, на самом деле это действительно, но выдаст загадочные предупреждения о warning: data definition has no type or storage class и warning: type defaults to ‘int’ in declaration of ‘x’ Однако, только потому, что он компилируется, он не будет делать то, что вы думаетебудут.На самом деле загадочные предупреждения, которые вы не понимаете, очень часто являются хорошим индикатором того, что код будет делать то, чего вы не хотите и не понимаете.Этот код выполняет неявное переопределение из x с последующей инициализацией .Это разрешено, если оно не было инициализировано ранее, поэтому это недопустимо:

int x = 3;
x = 5; // Not ok, because x is already initialized

И здесь сообщение об ошибке проясняет, почему скомпилирован предыдущий пример: error: redefinition of ‘x’.

Аналогично, это также недопустимо:

int x = foo();  

Выдает эту ошибку:

main.c:3:7: error: initializer element is not constant
 int x = foo();
         ^~~
2 голосов
/ 16 июня 2019

Как уже говорили другие. Вы не можете назначить в глобальной области видимости. Но вы можете инициализировать. Поэтому, если вы хотите инициализировать члены структуры глобально, вы можете попробовать это следующим образом.

#include <stdio.h>

typedef struct Light_System {
    int redLightPin;
    int yellowLightPin;
    int blueLightPin;
} Light_System;
Light_System ls = {10,5,3};

int main()

{
    printf("%d %d %d",ls.redLightPin,ls.yellowLightPin,ls.blueLightPin);
}

Это должно скомпилироваться.

Так что если вам интересно, почему это происходит, это потому, что глобальные переменные хранятся в разделе .data приложения с заданным значением во время компиляции. Но присваивания - это инструкции, которые могут быть выполнены только в рамках функции. То, что компилируется, сохраняет свое значение времени.

0 голосов
/ 16 июня 2019

Вы не можете выполнять операторы вне функции в C или C ++. Но вы можете использовать «обозначенные инициализаторы» в стиле C99 во многих компиляторах (не во всех):

Light_System system_1 = {
    .redLightPin = 4
};

Это станет стандартом в C ++ 20, но поскольку тот же синтаксис существует в C на протяжении многих лет, многие компиляторы также допускают его в C ++.

Ссылка: https://en.cppreference.com/w/cpp/language/aggregate_initialization

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...