My compiler raises the warning #381-D: extra ";" ignored in such a situation:
I have a struct defined, like the following
struct example_s
{
u8_t foo;
SOME_MACRO(bar);
};
The macro SOME_MACRO(x) does the following:
#if defined(SYSTEM_A)
#define SOME_MACRO(x) u16_t x##something
#else
#define SOME_MACRO(x) /* nothing */
#endif
Of course, the warning is correct, when SYSTEM_A is not defined. Simply because I have now a ; within the struct. But does someone know a way to avoid it correctly? I don't want to break the typical C-style by moving the ; into the macro.
One way that is a bit of a kludge but it seems to work with gcc:
#if defined(SYSTEM_A)
#define SOME_MACRO(x) u16_t x##something
#else
#define SOME_MACRO(x) int x[0] /* nothing */
#endif
With this method you end up with a struct like this:
struct example_s
{
u8_t foo;
int bar[0];
};
which has the correct size (i.e. as size as if bar had not been defined at all).
You can add an unnamed 0-width bitfield instead:
#if defined(SYSTEM_A)
#define SOME_MACRO(x) u16_t x##something
#else
#define SOME_MACRO(x) unsigned :0
#endif
you can also insert an empty anonymous struct :
#if defined(SYSTEM_A)
#define SOME_MACRO(x) u16_t x##something
#else
#define SOME_MACRO(x) struct {}
#endif
Related
I'm trying to write definitions for AVR C code so that i can access pins by simmple macro like
STATUS_LED_OUT =1;
in GENET_HW_DEF.h file, included to main C file. You can reproduce this bug by including this file into any C project.
I'm using avr studio 6.2 and 7 - both give the same result. I cannot compile getting werid macro unfold message like below. (CPU ATMega1284p)
D:\_SVN\Compass\AVR\Compass_IO_proto\Compass IO_proto\GENET_HW_DEF.h(19,49): error: expected ')' before '&' token
#define REGISTER_BIT(rg,bt) ((volatile _io_reg*)&rg)->bit##bt
^
D:\_SVN\Compass\AVR\Compass_IO_proto\Compass IO_proto\GENET_HW_DEF.h(42,25): info: in expansion of macro 'REGISTER_BIT'
#define STATUS_LED_OUT REGISTER_BIT(PORTB,7)
^
D:\_SVN\Compass\AVR\Compass_IO_proto\Compass IO_proto\GENET_HW_DEF.h(46,2): info: in expansion of macro 'STATUS_LED_OUT'
STATUS_LED_OUT=1;
^
Interesting enough, copied to fresh project with just only one or two declarations compiles fine, until one makes any changes in the declarations - like adding another macro reference. Then it becomes stuck again.
Also - if i comment all macro usages like
STATUS_LED_DIR=1;
STATUS_LED_OUT=1;
then I'm able to compile project and then after uncommenting usage lines it still compiles fine.. untill clean is executed. I'm probably messing with macro quirks but I have no idea where.
typedef struct
{
unsigned int bit0:1;
unsigned int bit1:1;
unsigned int bit2:1;
unsigned int bit3:1;
unsigned int bit4:1;
unsigned int bit5:1;
unsigned int bit6:1;
unsigned int bit7:1;
} _io_reg;
#define REGISTER_BIT(rg,bt) ((volatile _io_reg*)&rg)->bit##bt
#ifndef GENET_HW_DEF
#define GENET_HW_DEF
// define functionalities and flags - comment/uncomment apropriate lines
#define GENET_USART_0 256
#define GENET_USART_1 256
#define F_CPU 20000000UL
#define STATUS_LED 7
#define ERROR_LED 4
#define ADC_GLOBAL_ENABLE A
#define ADC_CHANNEL_0 0
#define ADC_CHANNEL_1 4
#define ADC_CHANNEL_2 2
#define ADC_CHANNEL_3 3
#define ADC_CHANNEL_4 1
#define ADC_CHANNEL_5 5
#define ADC_CHANNEL_6 6
#define ADC_CHANNEL_7 7
// actual definitions and initialization
#ifdef STATUS_LED
#define STATUS_LED_OUT REGISTER_BIT(PORTB,STATUS_LED)
#define STATUS_LED_DIR REGISTER_BIT(DDRB,STATUS_LED)
#define STATUS_LED_PIN REGISTER_BIT(PINB,STATUS_LED)
STATUS_LED_DIR=1;
STATUS_LED_OUT=1;
#endif
#ifdef ERROR_LED
#define ERROR_LED_OUT REGISTER_BIT(PORTC,ERROR_LED)
#define ERROR_LED_DIR REGISTER_BIT(DDRC,ERROR_LED)
ERROR_LED_DIR=1;
ERROR_LED_OUT=1;
#endif
#ifdef GENET_USART_0
#define USART0_ENABLED
#define UART_RX0_BUFFER_SIZE GENET_USART_0
#define UART_TX0_BUFFER_SIZE GENET_USART_0
#endif
#ifdef GENET_USART_1
#define USART1_ENABLED
#define UART_RX1_BUFFER_SIZE GENET_USART_1
#define UART_TX1_BUFFER_SIZE GENET_USART_1
#endif
#endif
I reproduced your problem.
You cannot call STATUS_LED_DIR=1; outside code execution flow. This must be inside a function (for example main()).
Now you will end with other compilation errors but this was the main mistake.
Second correction, you need 2 level for concatenation
#define CONCAT(bt) bit##bt
#define REGISTER_BIT(rg,bt) ((volatile _io_reg*)&rg)->CONCAT(bt)
im new with c language, but i try to unerstand this quark hashing algorithm that was written in c language, and i found an error while im compiling the source code, from what i understand the WIDTH it already declared, but why is it still error ?
this is the source code
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
/* uncomment to printf execution traces */
// #define DEBUG
#if defined(UQUARK)
#define CAPACITY 16
#define RATE 1
#define WIDTH 17
#elif defined(DQUARK)
#define CAPACITY 20
#define RATE 2
#define WIDTH 22
#endif
#define DIGEST WIDTH
typedef uint64_t u64;
typedef uint32_t u32;
typedef uint8_t u8;
typedef struct {
int pos; /* number of bytes read into x from current block */
// u32 x[ WIDTH*8 ]; /* one bit stored in each word */
u32 x[ WIDTH*8 ]; /* one bit stored in each word */
} hashState;
#if defined(UQUARK)
/* 17 bytes */
u8 iv[] = {0xd8,0xda,0xca,0x44,0x41,0x4a,0x09,0x97,
0x19,0xc8,0x0a,0xa3,0xaf,0x06,0x56,0x44,0xdb};
and its showing this error
quark.c:36:10: error : 'WIDTH' undeclared here (not in a function)
u32 x[WIDTH*8];
I guess for some reason neither UQUARK nor DQUARK are defined.
Add this:
#if defined(UQUARK) && defined(DQUARK)
#error both UQUARK and DQUARK are defined
#endif
#if !defined(UQUARK) && !defined(dQUARK)
#error Neither UQUARK nor DQUARK are defined
#endif
just before following line:
#if defined(UQUARK)
Then the compilation will abort if either both UQUARK and DQUARK are defined (which probably makes no sense) or if neither UQUARK nor DQUARK are defined (which probably happens in your case).
Now the question is: who defines UQUARK and/or DQUARK? Only you can tell.
I've been having some trouble setting up my libraries.
I'm looking forward to get a macro like PINSEL(P,N) with P as the number of the GPIO port and also N as the number of the pin in the port.
#ifndef uint32_t
typedef unsigned int uint32_t;
#endif
#ifndef __RW
#define __RW volatile
#endif
#ifndef __R
#define __R volatile const
#endif
typedef union{
struct {
uint32_t PINSELP4:2;
} PINSELP4[16];
struct{
__RW uint32_t PINSEL9_;
};
struct{
__RW uint32_t RES1_:24;
__RW uint32_t PINSELP4_28_:2;
__RW uint32_t PINSELP4_29_:2;
__RW uint32_t RES2_:4;
};
}PINSELP4_t;
#define PINSELP4_ ((PINSELP4_t *)(0x4002C024))
#define PINSELP4(N) PINSELP4_->PINSELP4_[N]->PINSELP4
#define PINSEL9 PINSELP4_->PINSEL9_
#define PINSELP4_28 PINSELP4_->PINSELP4_28_
#define PINSELP4_29 PINSELP4_->PINSELP4_29_
The example above shows the shorter struct of the 5 I've defined.
so then I've defined this two macros
#define PINSEL__(N)[] {PINSELP0(N),PINSELP1(N),PINSELP2(N),PINSELP3(N),PINSELP4(N)}
#define PINSEL(P,N) PINSEL__(N)[P]
I'm trying to make an "array of macros" for this to work. I'ts the only way I've figured it out. It still doesn't work. When I call the macro, I get
../src/../Includes/PINSEL_LPC1769.h:246:20: error: expected expression before '[' token
#define PINSEL__(N)[]={PINSELP0(N),PINSELP1(N),PINSELP2(N),PINSELP3(N),PINSELP4(N)}
^
as error.
I'm trying to make a really complete down layer so I can get a much clearer app layer. So if there's another way of doing this, I'll be listening.
Thank you all!
I try to make work the BLE121LR module with an external MCU (EFM32).
As I can understand, this piece of code declares converting of the struct to binary data, am I right?
Can somebody explain me how to add the ARM (EFM32) support for it?
Thanks a lot!!
Code:
/* Compability */
#ifndef PACKSTRUCT
#ifdef PACKED
#define PACKSTRUCT(a) a PACKED
#else
/*Default packed configuration*/
#ifdef __GNUC__
#ifdef _WIN32
#define PACKSTRUCT( decl ) decl __attribute__((__packed__,gcc_struct))
#else
#define PACKSTRUCT( decl ) decl __attribute__((__packed__))
#endif
#define ALIGNED __attribute__((aligned(0x4)))
#else //msvc
#define PACKSTRUCT( decl ) __pragma( pack(push, 1) ) decl __pragma( pack(pop) )
#define ALIGNED
#endif
#endif
#endif
Yes, packed structs affect how the struct is stored in memory, which is often used as a quick-and-dirty way of converting structs to binary data.
The PACKSTRUCT macro isn't written for the keil armcc compiler. To fix this, we must first find how we can identify when armcc is used. On this page, we can see that armcc provides the define __ARMCC_VERSION, which we can use.
Now, how do we declare a packed struct using armcc? Here, we see that we should use the __packed qualifier:
/* Compability */
#ifndef PACKSTRUCT
#ifdef PACKED
#define PACKSTRUCT(a) a PACKED
#else
/*Default packed configuration*/
#ifdef __GNUC__
#ifdef _WIN32
#define PACKSTRUCT( decl ) decl __attribute__((__packed__,gcc_struct))
#else
#define PACKSTRUCT( decl ) decl __attribute__((__packed__))
#endif
#define ALIGNED __attribute__((aligned(0x4)))
#else // not __GNUC__
#ifdef __ARMCC_VERSION
#define PACKSTRUCT( decl ) __packed decl
#define ALIGNED
#else // Assume msvc
#define PACKSTRUCT( decl ) __pragma( pack(push, 1) ) decl __pragma( pack(pop) )
#define ALIGNED
#endif
#endif
#endif
#endif
I have the following code and when I'm trying to compile it, I get an error:
error: ‘list_item_t’ has no member named ‘state’
Any creative ideas how to make this piece of code compile without warnings and erros?
#if defined (_DEBUG_)
#define ASSERT assert
#else /* _DEBUG_ */
#define ASSERT( exp ) ((void)(exp))
#endif`
typedef struct list_item {
struct list_item *p_next;
struct list_item *p_prev;
#ifdef _DEBUG_
int state;
#endif
} list_item_t;
main(int argc, char *argv)
{
list_item_t p_list_item;
ASSERT(p_list_item.state == 0);
}
Just #define ASSERT as
#if defined (_DEBUG_)
#define ASSERT assert
#else
#define ASSERT( exp ) (void)0
#endif
Note that this may change the behaviour of other code spots because ASSERT no longer evaluates its argument, but that's how people expect it to behave anyway.
Or perform a _DEBUG_ build, but this doesn't resolve the problem, it just avoids it.
Your class has the mentioned member if and only if _DEBUG_ is defined, and it apparently isn't.
#define _DEBUG_
in the beginning of your TU or change project settings to define it in some other way
This is due to
#define ASSERT( exp ) ((void)(exp))
which evaluates p_list_item.state == 0 and thus needs state to exist even when _DEBUG_ is not #define'd.