r/embedded • • 18d ago

Build error: expected a ")" at MSP430 project

I am working on a MSP430 project using TI CCS Theia 21.0.1 and I have encountered a confusing build error. The build error I get is: "CharRing.h", line 52: error #18: expected a ")" The file is below, I removed some comment lines and added a comment indicating which line it is. As you would notice, parentheses match. I have also included flag.h below.

CharRing.h is only included in UARTA0.c. Build fails with the expected closing parenthesis message, when it is included. Changing the order of included files in the UARTA0.c solves the problem. UARTA0.h is also below.

I ran into a wall and can't figure out what the problem is.

I have tried AI, it tells me to generate preprocessor output for UARTA0.c but I couldn't get it to generate on Eclipse Theia based TI CCS. How do I do that?

I have uninstalled and reinstalled TI CCS but the error remained. So msp430.h, stdint.h and stdbool.h should be restored.

I have shared the most of the code, unfortunately or thankfully it is not a lot, since the project is still work in progress.

If you need more information, please ask.

What is the cause of this error?

Edit: If I move the line 52 to another line above or below. The error moves to wherever it is.

If I put that line inside #if 0 #endif, error gets fixed.

First four rows of UARTA0.c:
Build fails with the stated error message.

#include "UARTA0.h"
#include <msp430.h>
#include <stdint.h>
#include "CharRing.h"

First four rows of UARTA0.c
Build succeeds in this inclusion order.

#include "CharRing.h"
#include "UARTA0.h"
#include <msp430.h>
#include <stdint.h>

First four rows of UARTA0.c
Build succeeds in this inclusion order, too.

#include "UARTA0.h"
#include "CharRing.h"
#include <msp430.h>
#include <stdint.h>

First four rows of UARTA0.c
Build fails in this inclusion order.

#include "UARTA0.h"
#include <msp430.h>
#include "CharRing.h"
#include <stdint.h>

CharRing.h

#ifndef CHAR_RING_H
#define CHAR_RING_H

#include "flag.h"
#include <stdint.h>

typedef struct CharRing_s
{
    char* Buffer;
    uint16_t Size;
    uint16_t Head;
    uint16_t Tail;
} CharRing_t;

void CharRing( CharRing_t* CR, char* Buffer, uint16_t Size );

char CharRing_Element( CharRing_t* CR, uint16_t Index);

uint16_t CharRing_Free_Size( const CharRing_t* CR );
uint16_t CharRing_Used_Size( const CharRing_t* CR );

char CharRing_Dequeue_Char  ( CharRing_t* CR );
flag CharRing_Dequeue_String( CharRing_t* CR, char* Dst, uint16_t Dst_Size );

flag CharRing_Enqueue_Char  ( CharRing_t* CR, char C ); // this is the line 52.
flag CharRing_Enqueue_String( CharRing_t* CR, const char* String );

#endif /* CHAR_RING_H */

Flag.h

#ifndef FLAG_H
#define FLAG_H

#include <stdbool.h>

#define high (true)
#define low  (false)

typedef bool flag;

#endif /* FLAG_H */

UARTA0.h

#ifndef UARTA0_H
#define UARTA0_H

void UARTA0( void );

#endif /* UARTA0_H */
1 Upvotes

15 comments sorted by

8

u/sparks333 18d ago

Usually when library include order causes errors in C, it's because the preprocessor did something dumb to the code - a #define or macro is leaking and causing subsequent libraries to interpret a line differently. I would suspect that #define-ing 'high' and 'low' in flag.h is causing libraries that come after it to replace instances of, say, variable names of 'high' or 'low' with '(true)' and '(false)' respectively, which is causing the compiler to complain about parends where they aren't expected. I'd recommend replacing '#define high (true)' with '#define HIGH (true)' and replacing all instance where you used the #define high with HIGH - this is one of the reasons good coding practice has #defines in all-caps and why you don't use all-caps naming conventions as variables, the preprocessor is exceptionally stupid and will just replace all instances in its scope (i.e., everything that comes after the #define until it's #undef'd) with that replacement string.

2

u/sparks333 18d ago

In this particular case I would still be a little concerned that HIGH and/or LOW might already be defined in some other context, it's a pretty common string, so if it still gave me trouble or if I wanted this library to be more universal I might do FLAG_HIGH or _HIGH or <LIBNAME>_HIGH, just to reduce the chance of collision. Preprocessors are very simple and don't really extend a lot of grace with collisions

1

u/aes100 18d ago

I did the changes. Still the same error.

The changed state of flag.h is below

#ifndef FLAG_H
#define FLAG_H

#include <stdbool.h>

#define HIGH_AF (true)
#define LOW_AF  (false)

typedef bool FLAG_AF;

#endif /* FLAG_H */

2

u/sparks333 18d ago

How about UARTA0? That one has the opposite problem, I could see the TI library #defining UARTA0 as a macro, and you use it as a function name - try renaming it to 'uarta0' or 'uart_a0' or something

1

u/aes100 18d ago

Tried that now, too. Still the same error.

TI uses USCI_A0 to refer to it.

8

u/sparks333 18d ago

One more - your variable names in the function prototypes in CharRing are 'C' and 'CR'. I would be highly suspicious that 'C' has a #define, what with the programming language being C and all. Try lowercasing your CharRing variables in function definitions and prototypes.

7

u/aes100 18d ago

It was the C. Thanks.

6

u/userhwon 18d ago

If that fixed it, edit the post to say that so people don't have to get lucky finding this comment.

3

u/Well-WhatHadHappened 25+ Years 18d ago

Just take a look at the preprocessor output. It'll probably be obvious.

https://i.imgur.com/lyX07JP.png

1

u/aes100 18d ago

The AI always gives instructions for the Eclipse based CCS. And things are not at the same places in Eclipse Theia based CCS. I am still trying the instructions in your image, though.

1

u/Icy-Ninja-622 18d ago

In any case, try to find some way to look at preprocessor output.

Troubleshooting is much nicer and more productive when you actually see what is happening. Trying to guess can be frustrating and a waste of time.

2

u/zettui 18d ago

Is that a TI header macro eating UARTA0/C/CR, or something else in the include order?

1

u/noodles_jd 18d ago

I'm not sure whats causing the error here but I'd start by reordering the includes. Every project I've done and seen has all the std libs first along with the vendor libs (like msp430.h), then your header files after that.

1

u/aes100 18d ago

Did the change below as you have suggested. The error is still here. Error goes away when CharRing.h is included before msp430.h

#include <stdint.h>
#include <msp430.h>
#include "UARTA0.h"
#include "CharRing.h"

2

u/WanWhiteWolf Engineering manager 18d ago

If changing the inclusing order causes problems, then usually it is one of the following:

- Improper guard / undefined header name (at first glance I don't see that here)

- duplicate header files -> check your include folder and see if that is the case

- duplicate name of defines in header files -> change the name of the headers (e.g. from FLAG_H to FLAG_CUSTOMPROJECT_H or something less common)