#define in an #include Header Not Appearing In Scope

Go To Last Post
24 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello Forum,

 

I think this maybe an Eclipse issue as I am pretty sure that if #include a header file I should have access to the header files #define values. However, I am positing as I am not 100% sure. An example.

 

uart.h

#ifndef UART_H
#define UART_H

#include <stdio.h>

#define DATA_BITS


void uart_init_9600( );
char uart_receive_byte( void );
void uart_receive_bytes( char buffer[], uint8_t maximum_buffer_size );
void uart_transmit_byte( uint8_t byte );
void uart_transmit_bytes( const char bytes[] );

#endif /* UART_H */

serial.h 

#include <avr/io.h> 		
#include <util/delay.h>		

#include "uart.h"

int main( void ) {

	uart_init_9600( );		/* works. */
	
    int dbs = DATA_BITS;    /* UNDECLARED. */
    
    for( ;; ) {
        uart_transmit_bytes( "Hello World!" ); /* works. */
        _delay_ms( 1000 );
    }
    return 0;
}

Both the uart_init_9600() and uart_transmit_bytes(char[]) works (as does any new function I create). I just can't get the DATA_BITS to be in scope.

 

Any idea will be gratefully received...

 

Kind Regards,

Harold Clements

Last Edited: Wed. Apr 29, 2015 - 03:24 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

haroldjclements wrote:
I am pretty sure that if #include a header file I should have access to the header files #define values

Yes, you should.

 

Quote:

uart.h

#ifndef UART_H  <---- Are you sure that nothing else has defined this??
#define UART_H

#include <stdio.h>

#define DATA_BITS  <---- You are defining the name - but you haven't given it any value!!


serial.h 

#include <avr/io.h> 		<---- High risk that UART_H might be defined by something in here?
#include <util/delay.h>		

#include "uart.h"

I just can't get the DATA_BITS to be in scope.

There is no such thing as "scope" with preprocessor symbols!

 

For preprocessor issues like this, the thing to do  is to look at the preprocessor output.

 

With GCC, use -save-temps 

 

https://gcc.gnu.org/onlinedocs/g...

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The preprocessor is mostly a simplistic textual replacer.

So

#define DATA_BITS (nothing)
int dbs = DATA_BITS;

 

gets preprocessed into

int dbs = (nothing);

No wonder the compiler complains.

 

JW

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:
There is no such thing as "scope" with preprocessor symbols!

https://www.avrfreaks.net/comment...

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You mean it is being reported as "undeclared" in your source browsing editor? Or that the compiler is saying that when this code is built?

 

If it's simply the editor, you are right, it's an Eclipse issue.

 

But wait a minute. What are you actually doing with "dbs" anyway? Your code is:

int main( void ) {
	uart_init_9600( );		/* works. */
	
    int dbs = DATA_BITS;    /* UNDECLARED. */
    
    for( ;; ) {
        uart_transmit_bytes( "Hello World!" ); /* works. */
        _delay_ms( 1000 );
    }
    return 0;
}

Any self respecting compiler is going to look at "dbs" there and say "that is completely pointless" and refuse to have anything to do with the variable. That's certainly true of GCC. It wont create anything called "dbs" here that can be watched or otherwise inspected unless you (a) make it volatile or (b) make it global (or (c) turn the optimiser off).

 

See my article in Tutorial about the importance of volatile in GCC to understand what's going on here.

 

EDIT: added hot-link to tutorial

Last Edited: Wed. Apr 29, 2015 - 03:02 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The convention is to put declarations in H files and code in C files.

 

Your #define simply removes DATA_BITS

 

So after the pre-processor has run, you get:

uart_init_9600( );		/* works. */
	
    int dbs = ;    /* UNDECLARED. */
    
    for( ;; ) {

which any decent compiler would barf at.

 

If you did happen to replace DATA_BITS with some real number like 16

uart_init_9600( );		/* works. */
	
    int dbs = 16;    /* UNDECLARED. */
    
    for( ;; ) {

You still would not see anything in the debugger.    Since dbs is never referenced,   the Optimiser has probably removed it.

 

Even if it was used,   it might have gone into a Register.    Studio is not very good at displaying variables that are in Registers.     (but it is a lot better than AS4)

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

wek3 wrote:
No wonder the compiler complains.

But I wouldn't have thought that it would complain about it being undeclared - as the OP suggests?

 

As you showed, it expands to literally nothing - so the compiler can't complain that nothing is undeclared!

 

surprise

 

If the compiler is complaining that DATA_BITS is undeclared, that means it must be seeing "DATA_BITS" in its input stream - which couldn't happen if the preprocessor had replaced it with nothing!

 

Hence my suspicion that the #define is not actually happening...

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:
So after the pre-processor has run, you get:

uart_init_9600( );		/* works. */
	
    int dbs = ;    /* UNDECLARED. */
    
    for( ;; ) {

which any decent compiler would barf at.

But see above - the barf would not be about anything being "undeclared".

 

Or maybe that comment is misleading ...

 

indecision

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you all for your quick responses.

 

The lack of value in the #define was a typo in this forum post. In the actual code it reads:

#define DATA_BITS   8

As for the pointless declaration:

int dbs = DATA_BITS;    /* UNDECLARED. */

This was just an example, to show that the #define was undeclared; I did not want to post 50+ lines of pointless code.

 

Kind Regards,

Harold Clements

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

haroldjclements wrote:
The lack of value in the #define was a typo in this forum post.

That is why you should never, ever manually type the code into a forum post - always copy and past!!

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

> I did not want to post 50+ lines of pointless code.

 

Well, create a minimal example exhibiting the problem, then.

 

>  always copy and past!!

 

... including the error messages.

 

JW

 

 

Last Edited: Wed. Apr 29, 2015 - 03:15 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sorry blush

 

To answer a question in the thread, the problem is not just Eclipse's code parsing, its also with the compiler output.

../serial_json.c: In function 'main':
../serial_json.c:44:12: error: 'DATA_BITS' undeclared (first use in this function)
  int dbs = DATA_BITS;
            ^
../serial_json.c:44:12: note: each undeclared identifier is reported only once for each function it appears in
../serial_json.c:44:6: warning: unused variable 'dbs' [-Wunused-variable]
  int dbs = DATA_BITS;
      ^
make: *** [serial_json.o] Error 1

There was a suggestion that using the name uart.h might be causing the issue, I will try changing it.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Put

#error "barf here"

just below

#define DATA_BITS

JW

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

My usual technique in this case is to add:

uart.h

#error "this file definitely being seen/used"
#ifndef UART_H
#define UART_H

#include <stdio.h>
 etc.

Now build - do you hit the #error? If not something is preventing this particular uart.h from being seen during the build.

 

If you do see the error then move it to the other side of the ifndef UART_H guard. How about now?

 

Ultimately put it on the line above/below the line where you think DATA_BITS is defined - how about now?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Jan and I clearly singing from the same song sheet! :-)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

haroldjclements wrote:
There was a suggestion that using the name uart.h might be causing the issue

No, that wasn't what I suggested!

 

https://www.avrfreaks.net/comment...

 

What I suggested was that the name of your include guard - UART_H - might be causing the issue.

 

And I suggested that you look at the preprocessor output to check.

 

But adding some judicious #errors, as others have suggested, would also do it...

 

PS

 

Does GCC support #warning or #message or similar...?

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

I get #error is thrown before and after #ifndef UART_H and #define UART_H and also...

In file included from ../uart.c:25:0:
../uart.h:23:2: error: #error "error before DATA_BITS define"
 #error "error before DATA_BITS define"
  ^
../uart.h:25:2: error: #error "error after DATA_BITS define"
 #error "error after DATA_BITS define"
  ^
make: *** [uart.o] Error 1

Thanks again for your time...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Time to look at  the preprocessor output, then...

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

My next guess is an "unprintable" in the text of:

    int dbs = DATA_BITS;    /* UNDECLARED. */

so it's not matching "DATA_BITS" that we now know is defined in uart.h.

 

Either that or the int dbs= line is just an innocent victim of some error on a preceding line within the 50 lines we didn't get to see above it?

 

A further technique in debugging headers is that GCC has a switch to tell the preprocessor to announce all the .h files it is processing and the order in which that occurs. That could be "interesting" but be ready for a lot of very verbose output!

 

EDIT just reminded myself it is -H. Wouldn't you know it would be virtually the last option on this page in the manual..

 

https://gcc.gnu.org/onlinedocs/g...

 

to pass -H to the pre-pro (not compiler or linker) invoke avr-gcc but use -Wp,-H which passes the option on to the pre-pro.

 

EDIT2: an example on a file that has an empty main() and just includes <avr/io.h>...

~$ avr-gcc -mmcu=atmega16 -Wp,-H avr.c -o avr.elf
. /usr/lib/gcc/avr/4.5.3/../../../avr/include/avr/io.h
.. /usr/lib/gcc/avr/4.5.3/../../../avr/include/avr/sfr_defs.h
... /usr/lib/gcc/avr/4.5.3/../../../avr/include/inttypes.h
.... /usr/lib/gcc/avr/4.5.3/include/stdint.h
..... /usr/lib/gcc/avr/4.5.3/../../../avr/include/stdint.h
.. /usr/lib/gcc/avr/4.5.3/../../../avr/include/avr/iom16.h
.. /usr/lib/gcc/avr/4.5.3/../../../avr/include/avr/portpins.h
.. /usr/lib/gcc/avr/4.5.3/../../../avr/include/avr/common.h
.. /usr/lib/gcc/avr/4.5.3/../../../avr/include/avr/version.h
.. /usr/lib/gcc/avr/4.5.3/../../../avr/include/avr/fuse.h
.. /usr/lib/gcc/avr/4.5.3/../../../avr/include/avr/lock.h
$

(who knew there were two stdint.h's ?!?)

Last Edited: Wed. Apr 29, 2015 - 03:49 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

My next guess is an "unprintable" in the text of:

    int dbs = DATA_BITS;    /* UNDECLARED. */

so it's not matching "DATA_BITS" that we now know is defined in uart.h.

Or, perhaps, an unprintable in the definition in uart.h - so that it is actually defining something other than "DATA_BITS"

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you again, I will open the uart.h file in a hex editor and check for a "unprintable" character, then try the header debugging...(watch this space)...

 

Thanks again for all your time a effort guys, it's very much appreciated...

 

Kind Regards,

Harold Clements

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

> unprintable

 

... in which case the recommendation changes from "copy and paste" to "zip and post"...

 

JW

 

 

(PS. Andy, copy and past, nice typo ;-) )
 

Last Edited: Wed. Apr 29, 2015 - 04:07 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You also need to do the same check on the .c file that's trying to use "DATA_BITS"...

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK guys, I know the problem is with Eclipse. I have created my own "make" file and all builds...

 

I don't have a clue what my miss-configuration is in Eclipse, but I am going  to have fun finding out (or not!).

 

Cheers Guys...

Harold Clements