2012-04-02 4 views
0

Я хочу, чтобы порт проекта с использованием gcc для компилятора IAR, но IAR жалуется на несколько функций, используя void * как формальный параметр.Почему IAR бросает ошибку на void *

struct 
{ 
    uint16_t ConnectionHandle; 
    uint8_t Reason; 
}DisconnectParams; 

прототип функции

bool Bluetooth_HCI_SendControlPacket(BT_StackConfig_t* const StackState, 
            const uint16_t OpCode, 
            const uint8_t Length, 
            const void* Data); 

и использования является:

Bluetooth_HCI_SendControlPacket(StackState, (OGF_LINK_CONTROL | OCF_LINK_CONTROL_DISCONNECT), sizeof(DisconnectParams), &DisconnectParams); 

Здесь жалуются ошибки [Pe167]: аргумент типа "STRUCT *" несовместима с параметром тип "void const *"

И еще одно место

static inline void SDP_WriteData8(void** BufferPos,const uint8_t Data) 
{ 
*((uint8_t*)*BufferPos) = Data; 
*BufferPos += sizeof(uint8_t); 
} 

Ошибка [Pe852]: выражение должно быть указателем на полный тип объекта. Как я знаю, void * может принимать любой указатель, Как изменить код, чтобы удалить эти ошибки? Благодаря!

Крис

+0

Можете ли вы предоставить более подробную информацию о версии IAR и настройках проекта? Я не могу воспроизвести первую проблему с помощью IAR 5.40. – tinman

+0

My IAR - EWARM 6.30.1, настройка C99 и разрешение VLA (массив переменной длины), но значение -vla кажется неэффективным, поскольку оно все еще жалуется, что выражение должно иметь постоянное значение, когда я определяю массив переменных uint8_t Data [ DataLen]; – user1308274

+0

Что такое целевое устройство? –

ответ

3

С точки зрения вашего второго вопроса, что код неверен, потому что у вас есть пустота *, и вы пытаетесь увеличить на SizeOf (uint8_t) (я предполагаю, 1). Это эквивалентно:

void *p; 
p += 1; 

Вы не можете выполнять указатель arithmatic на указатель, который имеет неполную типа, потому что компилятор не знает, как значение увеличивается на (помните, что это идет по размеру указываемого объекта) ,

Вы, вероятно, должны были указывать указатель на указатель uint8_t перед увеличением.

+0

Спасибо за ваш ответ. Хорошо, я понимаю ваш ответ. Но другой вопрос в том, почему gcc может скомпилировать его. – user1308274

+0

Возможно, существует расширение gcc, которое автоматически предполагает, что вы хотите добавить в байты приращения, если вы добавляете значения в указатель void? Извините, я не знаю точно, поскольку я не использую gcc. – tinman

+0

У GCC есть такое расширение: http://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Pointer-Arith.html#Pointer-Arith –

0
#ifdef I_JUST_LOVE_MYSTERIOUS_COMPILER_ERRORS 
    struct 
    { 
    uint16_t ConnectionHandle; 
    uint8_t Reason; 
    }DisconnectParams; 
#else 
    typedef struct 
    { 
    uint16_t ConnectionHandle; 
    uint8_t Reason; 
    }DisconnectParams_t; 

    DisconnectParams_t DisconnectParams; 
#endif 
+0

Это действительно помогает? Если это так, я не могу понять, почему - как компилятор может принять адрес типа в качестве аргумента для вызова функции? Как это можно оценить? –

+0

@MichaelBurr Я понятия не имею, информации слишком мало. Однако, похоже, это одна из вероятных проблем. Попробуйте. – Lundin

+0

@lundin - это не сработает: 'struct {...} DisconnectParams' определяет неназванную структуру и объявляет переменную (называемую DisconnectParams) этого типа за один раз; 'typedef struct {...} DisconnectParams' определяет неназванную структуру и объявляет синоним для этого типа (с именем DisconnectParams). DisconnectParams в первом случае является переменной, во втором типе. Во втором случае вызов 'Bluetooth_HCI_SendControlPacket' с' & DisconnectParams' определенно будет ошибкой компилятора ... – Attila

Смежные вопросы