Ошибка при присвоении значения элементу массива

Что мне нужно сделать: изменить код ядра Linux (3.13.6, загруженный с kernel.org). Найдите количество вызовов функции kvm_vmx_exit_handler.

Что я пытаюсь сделать: объявить массив в файле x86.h.

 extern unsigned long int my_count_s[40];

файл x86.h, который включается в файл 'vmx.c'

#include "x86.h"

Теперь я пытаюсь инициализировать элемент массива значением 0 в файле 'vmx.c'.

my_count_s[1] = 0;

Я буду увеличивать его каждый раз, когда вызывается функция kvm_exit_handler. И я узнаю, сколько раз kvm выполнял выход, когда что-то происходило, и сколько раз вызывалась конкретная функция обработки выхода. Я буду использовать один элемент массива для каждой функции exithandler.

Ошибка, с которой я столкнулся:

arch/x86/kvm/vmx.c:58:1: warning: data definition has no type or storage class [enabled by default]
arch/x86/kvm/vmx.c:58:1: error: type defaults to ‘int’ in declaration of ‘my_count_s’ [-Werror=implicit-int]
arch/x86/kvm/vmx.c:58:1: error: conflicting types for ‘my_count_s’
arch/x86/kvm/x86.h:8:26: note: previous declaration of ‘my_count_s’ was here
arch/x86/kvm/vmx.c:58:1: error: invalid initializer

Мое понимание: я объявил тип данных my_count_s[40] как unsigned long int, но почему по умолчанию используется значение 'int'? И даже если он был задан по умолчанию для типа данных 'int', почему возникла ошибка инициализации для строки my_count_s[1] = 0; ?

ПРИМЕЧАНИЕ: 1. Строка 58 в файле vmx.c — это "my_count_s[1]=0;" 2. Если я скомпилирую ядро, просто объявив массив, оно работает нормально, но всплывают ошибки, когда я пытаюсь присвоить значение элементу в массиве.


person user3543477    schedule 07.05.2014    source источник


Ответы (2)


Операторы, включая присваивания, должны быть внутри функций. Бьюсь об заклад, ваш находится вне функции.

Компилятор сбит с толку, потому что = может появляться только в объявлениях и операторах, а поскольку он находится вне функции, ваша строка анализируется как объявление. Это просто не работает; где тип?

person MSalters    schedule 07.05.2014
comment
Эх... хороший улов. OP пытается инициализировать массив с неправильным синтаксисом. - person Jonathon Reinhart; 08.05.2014
comment
@MSalters: Большое спасибо за указание на это :) Я много использовал python и привык присваивать значения переменным вне функций. - person user3543477; 08.05.2014

Проблема в том, что, даже если у вас есть это в вашем заголовочном файле:

extern unsigned long int my_count_s[40];

вы еще нигде не определили массив — вы только объявили, что он существует где-то.

В каком-то исходном файле (вероятно, arch/x6/kvm/vmx.c) вам нужно определить массив:

unsigned long int my_count_s[40];

Помните, extern говорит: «Эй, компилятор, эта переменная существует в каком-то модуле». Вот почему мы помещаем extern декларации в заголовочные файлы. На самом деле они не приводят к выделению места для переменной, они просто указывают на ее существование.

Строка без extern является определением и помещается в файл .c. Именно в этой единице компиляции фактически зарезервировано место для переменной.


На другой заметке. Эта переменная должна быть глобальной? Если arch/x6/kvm/vmx.c — единственный файл, который на него ссылается, то его не должно быть в заголовочном файле, и он должен быть помечен как static в файле .c:

static unsigned long int my_count_s[40];

Здесь static ограничивает свою видимость только файлом C, в котором он определен.

person Jonathon Reinhart    schedule 07.05.2014
comment
поэтому я должен использовать unsigned long int my_count_s[40]; в файле заголовка, а затем использовать unsinged long int my_count_s[40]; в файле vmx.c, а затем использовать my_count_s[1] = 0; для присвоения значения второму элементу в массиве?? - person user3543477; 08.05.2014
comment
Нет нет нет. Не помещайте определения глобальных переменных в заголовочный файл! Это приведет к тому, что переменная будет определена в каждом файле C, который ее включает. - person Jonathon Reinhart; 08.05.2014
comment
Я попытался объявить массив и использовать его в файле vmx.c, и я столкнулся с той же ошибкой (те же ошибки при присвоении значения элементу в массиве), и поэтому я следовал этому подходу, предложенному мой друг. - person user3543477; 08.05.2014
comment
Я не уверен, что предложил ваш друг, но у вас есть весь исходный код ядра в качестве хорошего примера. Все просто: объявления (т. е. прототипы функций и externd глобальных переменных) помещаются в файлы заголовков, а определения (функции с телами и глобальные переменные) — в файлы .C. . - person Jonathon Reinhart; 08.05.2014
comment
Первое, что я сделал, это объявил массив в файле vmc.c, используя 'static unsigned long int my_count_s[40];' а затем присвоить значение элемента с помощью my_count_s[40];. Я получал те же ошибки (type defaults to ‘int’ in declaration of ‘my_count_s’ и conflicting types for ‘my_count_s’ и invalid initializer) - person user3543477; 08.05.2014
comment
Вы поместили этот глобальный файл в начало файла? Кроме того, у вас нет my_count_s[1] = 0; вне функции, не так ли? - person Jonathon Reinhart; 08.05.2014
comment
да, объявление было в верхней части файла. Плохо, я привык присваивать значения вне функций и не понимал, что это не работает в C. Спасибо за ваше время. Ваши комментарии действительно помогли мне в использовании файлов заголовков. :) - person user3543477; 08.05.2014