Конструктор копирования для C volatile структуры битовых полей

Добрый день

Я пытаюсь использовать драйвер C SD / библиотеку файловой системы (Keil MDK) в проекте C ++ 11. Он был добавлен менеджером пакетов в Keil MDK 5.23. Я собираю с ARMCC 5.06u4

Я получаю предупреждение class "_ARM_MCI_STATUS" не имеет подходящего конструктора копирования «, что странно, потому что заголовок, в котором он объявлен, имеет extern "C" {,

По умолчанию пакет не имеет возможности установить его на C или C ++, но я вручную добавил файл в виде файла C. Все еще проблема.

Структура объявлена, в пределах extern "C" { как:

typedef volatile struct _ARM_MCI_STATUS {
uint32_t command_active   : 1;        ///< Command active flag
uint32_t command_timeout  : 1;        ///< Command timeout flag (cleared on start of next command)
uint32_t command_error    : 1;        ///< Command error flag (cleared on start of next command)
uint32_t transfer_active  : 1;        ///< Transfer active flag
uint32_t transfer_timeout : 1;        ///< Transfer timeout flag (cleared on start of next command)
uint32_t transfer_error   : 1;        ///< Transfer error flag (cleared on start of next command)
uint32_t sdio_interrupt   : 1;        ///< SD I/O Interrupt flag (cleared on start of monitoring)
uint32_t ccs              : 1;        ///< CCS flag (cleared on start of next command)
uint32_t reserved         : 24;
} ARM_MCI_STATUS;

Проблема возникает, когда структура возвращается в:

static ARM_MCI_STATUS GetStatus (MCI_RESOURCES *mci) {
return mci->info->status;
}

куда status объявлен как ARM_MCI_STATUS status;, Я не понимаю, почему это должно быть проблемой.

Если я компилирую без —cpp, то он компилируется без проблем.

Какие-либо предложения?

2

Решение

Просто потому, что ваш struct отмечен extern "C" не означает, что он все равно не будет скомпилирован как код C ++.

Это означает, что return mci->info->status; вызывает неявно сгенерированный конструктор копирования.
Так как _ARM_MCI_STATUS отмечен volatile, это члены, что означает конструктор копирования по умолчанию, который принимает T& не может связываться с изменяемой ссылкой lvalue, которую она передала.

Это объясняется в объяснение:

В противном случае неявно объявленным конструктором копирования является T :: T (T).&). (Заметка
что из-за этих правил неявно объявленный конструктор копирования
не может связываться с изменчивым аргументом lvalue.
)

А также в действующем стандарте (просто трудно найти правильное предложение, но оно там).

3

Другие решения

В C ++ конструктор копирования по умолчанию предназначен для константной ссылки.
Вы, однако, переходите в постоянную изменчивую ссылку; и по умолчанию для этого не создается конструктор копирования.

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

3

Чтобы решить эту проблему в Keil µVision 5.23, я удалил глобальные флаги «—cpp». Затем я убедился, что все файлы C ++ находятся в своих собственных исходных группах в проекте. В опциях для этой группы на вкладке «C / C ++» в поле «Misc Controls» добавлен флаг «—cpp».

Опции можно получить, щелкнув правой кнопкой мыши на папке в представлении проекта.

Вкладка «Параметры» для группы источников Cpp

На данный момент он компилируется без ошибок. Кажется, проблема в том, что µVision 5.23 скомпилирует все файлы, c или cpp, как C ++, если флаг —cpp установлен глобально. В отличие от Eclipse, кажется, нет способа установить разные флаги для файлов cpp и c.

Спасибо UKMonkey и Рику Эстли. Узнал кое-что о volatile и C ++.

0
По вопросам рекламы [email protected]