using multiple files

i've been coding for a couple of years now. i mostly write projects for embedded microchip pic processors. up until now i've used c. now i'm making my way to a new processor that supports c++ and nothing works.

i've read everything i could find organizing files and i've applied what i've read to my c code which works great.

the code that follow compiles with no problems

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
// main.c /****************************************/
void main(void) {
    while(1);
}

//buffer.h /****************************************/
#ifndef BUFFER_H
#define	BUFFER_H

#ifdef	__cplusplus
extern "C" {
#endif

#define BUFFER_SIZE 20
    
    struct Buff {
        unsigned char data[BUFFER_SIZE];
        int head;
        int tail;
        int count;
    };

    struct Buff ring_buffer;

    void BufferPut(struct Buff* _where_to_store, int received_data);
    unsigned int modulo_inc(const unsigned int value, const unsigned int modulus);



#ifdef	__cplusplus
}
#endif

#endif	/* BUFFER_H */

//buffer.c /****************************************/
#include "buffer.h"


// place data in the buffer
void BufferPut(struct Buff* _where_to_store, int received_data) {
    if (_where_to_store->count < BUFFER_SIZE) {
        _where_to_store->data[_where_to_store->head] = received_data;
        _where_to_store->head = modulo_inc(_where_to_store->head, BUFFER_SIZE);
        ++_where_to_store->count;
    }else{
        _where_to_store->data[_where_to_store->head] = received_data;
        _where_to_store->head = modulo_inc(_where_to_store->head, BUFFER_SIZE);
        _where_to_store->tail = modulo_inc(_where_to_store->tail, BUFFER_SIZE);
    }
}

// used to service the subroutines of the ring buffer
unsigned int modulo_inc(const unsigned int value, const unsigned int modulus) {
    unsigned int my_value = value + 1;
    if (my_value >= modulus) {
        my_value = 0;
    }
    return (my_value);
}

//interrupt.h /****************************************/
#ifndef INTERRUPT_H
#define	INTERRUPT_H

#ifdef	__cplusplus
extern "C" {
#endif

void __ISR(_UART_1_VECTOR, IPL1SRS) UARThandler(void);


#ifdef	__cplusplus
}
#endif

#endif	/* INTERRUPT_H */

//interrupt.c /****************************************/
#include <xc.h> //hardware interface for the processor
#include <sys/attribs.h> //interrupt interface for processor
#include "interrupt.h"
#include "buffer.h"


// interrupt service rutine. stops the execution of the main code and
// runs function when a byte is recieved by the UART
// after function is complete the main code picks back up where it left off
void __ISR(_UART_1_VECTOR, IPL1SRS) UARThandler(void){

    BufferPut(&ring_buffer, U1RXREG);

}


then all i do is change the c files to cpp files and the code no longer compiles

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
// main.cpp /****************************************/
int main(void) {
    while(1);
return 0;
}

//buffer.h /****************************************/
#ifndef BUFFER_H
#define	BUFFER_H

#ifdef	__cplusplus
extern "C" {
#endif

#define BUFFER_SIZE 20
    
    struct Buff {
        unsigned char data[BUFFER_SIZE];
        int head;
        int tail;
        int count;
    };

    struct Buff ring_buffer;

    void BufferPut(struct Buff* _where_to_store, int received_data);
    unsigned int modulo_inc(const unsigned int value, const unsigned int modulus);



#ifdef	__cplusplus
}
#endif

#endif	/* BUFFER_H */

//buffer.cpp /****************************************/
#include "buffer.h"


// place data in the buffer
void BufferPut(struct Buff* _where_to_store, int received_data) {
    if (_where_to_store->count < BUFFER_SIZE) {
        _where_to_store->data[_where_to_store->head] = received_data;
        _where_to_store->head = modulo_inc(_where_to_store->head, BUFFER_SIZE);
        ++_where_to_store->count;
    }else{
        _where_to_store->data[_where_to_store->head] = received_data;
        _where_to_store->head = modulo_inc(_where_to_store->head, BUFFER_SIZE);
        _where_to_store->tail = modulo_inc(_where_to_store->tail, BUFFER_SIZE);
    }
}

// used to service the subroutines of the ring buffer
unsigned int modulo_inc(const unsigned int value, const unsigned int modulus) {
    unsigned int my_value = value + 1;
    if (my_value >= modulus) {
        my_value = 0;
    }
    return (my_value);
}

//interrupt.h /****************************************/
#ifndef INTERRUPT_H
#define	INTERRUPT_H

#ifdef	__cplusplus
extern "C" {
#endif

void __ISR(_UART_1_VECTOR, IPL1SRS) UARThandler(void);


#ifdef	__cplusplus
}
#endif

#endif	/* INTERRUPT_H */

//interrupt.cpp /****************************************/
#include <xc.h> //hardware interface for the processor
#include <sys/attribs.h> //interrupt interface for processor
#include "interrupt.h"
#include "buffer.h"


// interrupt service rutine. stops the execution of the main code and
// runs function when a byte is recieved by the UART
// after function is complete the main code picks back up where it left off
void __ISR(_UART_1_VECTOR, IPL1SRS) UARThandler(void){

    BufferPut(&ring_buffer, U1RXREG);

}


i've included all of the "inclusion guards" but i get multiple definition errors and i have no idea why. what am i doing wrong?




build/default/production/main.o: In function `main':
c:/users/igor/mplabxprojects/testpic32.x/main.cpp:4: multiple definition of `main'
build/default/production/main.o:c:/users/igor/mplabxprojects/testpic32.x/main.cpp:4: first defined here
build/default/production/interrupt.o: In function `UARThandler':
c:/users/igor/mplabxprojects/testpic32.x/interrupt.cpp:10: multiple definition of `ring_buffer'
build/default/production/interrupt.o:c:/users/igor/mplabxprojects/testpic32.x/interrupt.cpp:10: first defined here
build/default/production/interrupt.o: In function `UARThandler':
c:/users/igor/mplabxprojects/testpic32.x/interrupt.cpp:10: multiple definition of `UARThandler'
build/default/production/interrupt.o:c:/users/igor/mplabxprojects/testpic32.x/interrupt.cpp:10: first defined here
build/default/production/interrupt.o: In function `__vector_dispatch_24':
c:/users/igor/mplabxprojects/testpic32.x/interrupt.cpp:(.vector_24+0x0): multiple definition of `__vector_dispatch_24'
build/default/production/interrupt.o:c:/users/igor/mplabxprojects/testpic32.x/interrupt.cpp:(.vector_24+0x0): first defined here
build/default/production/buffer.o: In function `BufferPut':
c:/users/igor/mplabxprojects/testpic32.x/buffer.cpp:5: multiple definition of `ring_buffer'
build/default/production/interrupt.o:c:/users/igor/mplabxprojects/testpic32.x/interrupt.cpp:10: first defined here
build/default/production/buffer.o: In function `BufferPut':
c:/users/igor/mplabxprojects/testpic32.x/buffer.cpp:5: multiple definition of `ring_buffer'
build/default/production/interrupt.o:c:/users/igor/mplabxprojects/testpic32.x/interrupt.cpp:10: first defined here
build/default/production/buffer.o: In function `BufferPut':
c:/users/igor/mplabxprojects/testpic32.x/buffer.cpp:5: multiple definition of `BufferPut'
build/default/production/buffer.o:c:/users/igor/mplabxprojects/testpic32.x/buffer.cpp:5: first defined here
build/default/production/buffer.o: In function `modulo_inc':
c:/users/igor/mplabxprojects/testpic32.x/buffer.cpp:18: multiple definition of `modulo_inc'
build/default/production/buffer.o:c:/users/igor/mplabxprojects/testpic32.x/buffer.cpp:18: first defined here
c:\program files\microchip\xc32\v1.32\bin\bin\gcc\pic32mx\4.5.2\..\..\..\..\bin/xc32-ld.exe: Link terminated due to previous error(s).
collect2: ld returned 255 exit status
make[2]: *** [dist/default/production/testpic32.X.production.hex] Error 255
make[1]: *** [.build-conf] Error 2
make: *** [.build-impl] Error 2
make[2]: Leaving directory `C:/Users/Igor/MPLABXProjects/testpic32.X'
make[1]: Leaving directory `C:/Users/Igor/MPLABXProjects/testpic32.X'

BUILD FAILED (exit value 2, total time: 1s)
Please post your build method.

An obvious error is that both the compile of interrupt.cpp and buffer.cpp will declare:
struct Buff ring_buffer;
because they both include buffer.h. So the linker should say
multiple definition of `ring_buffer'

This should be the case with C and C++.
So you want to declare it extern in the .h file, and define it in only one of the .cpp files.


this is where my understanding gets fuzzy. i thought that the inclusion guards are so posed to keep multiple definition issues from happening. that if BUFFER_H is already declared then don't declare it again resulting in a single definition of ring_buffer or does this only hold true for function prototypes?

should i only include function prototypes and externrd variable is my header files?


the IDE i'm using (MPLABX) build the project automatically. the best i cant tell this is how the project is built. (i'ts too large to post in a singe entry. i'll post it in two parts)


#
# Generated Makefile - do not edit!
#
# Edit the Makefile in the project folder instead (../Makefile). Each target
# has a -pre and a -post target defined where you can add customized code.
#
# This makefile implements configuration specific macros and targets.


# Include project Makefile
ifeq "${IGNORE_LOCAL}" "TRUE"
# do not include local makefile. User is passing all local related variables already
else
include Makefile
# Include makefile containing local settings
ifeq "$(wildcard nbproject/Makefile-local-default.mk)" "nbproject/Makefile-local-default.mk"
include nbproject/Makefile-local-default.mk
endif
endif

# Environment
MKDIR=gnumkdir -p
RM=rm -f 
MV=mv 
CP=cp 

# Macros
CND_CONF=default
ifeq ($(TYPE_IMAGE), DEBUG_RUN)
IMAGE_TYPE=debug
OUTPUT_SUFFIX=elf
DEBUGGABLE_SUFFIX=elf
FINAL_IMAGE=dist/${CND_CONF}/${IMAGE_TYPE}/testpic32.X.${IMAGE_TYPE}.${OUTPUT_SUFFIX}
else
IMAGE_TYPE=production
OUTPUT_SUFFIX=hex
DEBUGGABLE_SUFFIX=elf
FINAL_IMAGE=dist/${CND_CONF}/${IMAGE_TYPE}/testpic32.X.${IMAGE_TYPE}.${OUTPUT_SUFFIX}
endif

# Object Directory
OBJECTDIR=build/${CND_CONF}/${IMAGE_TYPE}

# Distribution Directory
DISTDIR=dist/${CND_CONF}/${IMAGE_TYPE}

# Source Files Quoted if spaced
SOURCEFILES_QUOTED_IF_SPACED=main.cpp main.c interrupt.cpp interrupt.c buffer.c buffer.cpp

# Object Files Quoted if spaced
OBJECTFILES_QUOTED_IF_SPACED=${OBJECTDIR}/main.o ${OBJECTDIR}/main.o ${OBJECTDIR}/interrupt.o ${OBJECTDIR}/interrupt.o ${OBJECTDIR}/buffer.o ${OBJECTDIR}/buffer.o
POSSIBLE_DEPFILES=${OBJECTDIR}/main.o.d ${OBJECTDIR}/main.o.d ${OBJECTDIR}/interrupt.o.d ${OBJECTDIR}/interrupt.o.d ${OBJECTDIR}/buffer.o.d ${OBJECTDIR}/buffer.o.d

# Object Files
OBJECTFILES=${OBJECTDIR}/main.o ${OBJECTDIR}/main.o ${OBJECTDIR}/interrupt.o ${OBJECTDIR}/interrupt.o ${OBJECTDIR}/buffer.o ${OBJECTDIR}/buffer.o

# Source Files
SOURCEFILES=main.cpp main.c interrupt.cpp interrupt.c buffer.c buffer.cpp


CFLAGS=
ASFLAGS=
LDLIBSOPTIONS=

############# Tool locations ##########################################
# If you copy a project from one host to another, the path where the  #
# compiler is installed may be different.                             #
# If you open this project with MPLAB X in the new host, this         #
# makefile will be regenerated and the paths will be corrected.       #
#######################################################################
# fixDeps replaces a bunch of sed/cat/printf statements that slow down the build
FIXDEPS=fixDeps

.build-conf:  ${BUILD_SUBPROJECTS}
	${MAKE} ${MAKE_OPTIONS} -f nbproject/Makefile-default.mk dist/${CND_CONF}/${IMAGE_TYPE}/testpic32.X.${IMAGE_TYPE}.${OUTPUT_SUFFIX}

MP_PROCESSOR_OPTION=32MX575F512H
MP_LINKER_FILE_OPTION=
# ------------------------------------------------------------------------------------
# Rules for buildStep: assemble
ifeq ($(TYPE_IMAGE), DEBUG_RUN)
else
endif

# ------------------------------------------------------------------------------------
# Rules for buildStep: assembleWithPreprocess
ifeq ($(TYPE_IMAGE), DEBUG_RUN)
else
endif

# ------------------------------------------------------------------------------------
# Rules for buildStep: compile
ifeq ($(TYPE_IMAGE), DEBUG_RUN)
${OBJECTDIR}/main.o: main.c  nbproject/Makefile-${CND_CONF}.mk
	@${MKDIR} ${OBJECTDIR} 
	@${RM} ${OBJECTDIR}/main.o.d 
	@${RM} ${OBJECTDIR}/main.o 
	@${FIXDEPS} "${OBJECTDIR}/main.o.d" $(SILENT) -rsi ${MP_CC_DIR}../  -c ${MP_CPPC}  $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist  -x c -c -mprocessor=$(MP_PROCESSOR_OPTION)  -MMD -MF "${OBJECTDIR}/main.o.d" -o ${OBJECTDIR}/main.o main.c   
	
${OBJECTDIR}/interrupt.o: interrupt.c  nbproject/Makefile-${CND_CONF}.mk
	@${MKDIR} ${OBJECTDIR} 
	@${RM} ${OBJECTDIR}/interrupt.o.d 
	@${RM} ${OBJECTDIR}/interrupt.o 
	@${FIXDEPS} "${OBJECTDIR}/interrupt.o.d" $(SILENT) -rsi ${MP_CC_DIR}../  -c ${MP_CPPC}  $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist  -x c -c -mprocessor=$(MP_PROCESSOR_OPTION)  -MMD -MF "${OBJECTDIR}/interrupt.o.d" -o ${OBJECTDIR}/interrupt.o interrupt.c   
	
${OBJECTDIR}/buffer.o: buffer.c  nbproject/Makefile-${CND_CONF}.mk
	@${MKDIR} ${OBJECTDIR} 
	@${RM} ${OBJECTDIR}/buffer.o.d 
	@${RM} ${OBJECTDIR}/buffer.o 
	@${FIXDEPS} "${OBJECTDIR}/buffer.o.d" $(SILENT) -rsi ${MP_CC_DIR}../  -c ${MP_CPPC}  $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist  -x c -c -mprocessor=$(MP_PROCESSOR_OPTION)  -MMD -MF "${OBJECTDIR}/buffer.o.d" -o ${OBJECTDIR}/buffer.o buffer.c   
	
else
${OBJECTDIR}/main.o: main.c  nbproject/Makefile-${CND_CONF}.mk
	@${MKDIR} ${OBJECTDIR} 
	@${RM} ${OBJECTDIR}/main.o.d 
	@${RM} ${OBJECTDIR}/main.o 
	@${FIXDEPS} "${OBJECTDIR}/main.o.d" $(SILENT) -rsi ${MP_CC_DIR}../  -c ${MP_CPPC}  $(MP_EXTRA_CC_PRE)  -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION)  -MMD -MF "${OBJECTDIR}/main.o.d" -o ${OBJECTDIR}/main.o main.c   
	
${OBJECTDIR}/interrupt.o: interrupt.c  nbproject/Makefile-${CND_CONF}.mk
	@${MKDIR} ${OBJECTDIR} 
	@${RM} ${OBJECTDIR}/interrupt.o.d 
	@${RM} ${OBJECTDIR}/interrupt.o 
	@${FIXDEPS} "${OBJECTDIR}/interrupt.o.d" $(SILENT) -rsi ${MP_CC_DIR}../  -c ${MP_CPPC}  $(MP_EXTRA_CC_PRE)  -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION)  -MMD -MF "${OBJECTDIR}/interrupt.o.d" -o ${OBJECTDIR}/interrupt.o interrupt.c   
	
${OBJECTDIR}/buffer.o: buffer.c  nbproject/Makefile-${CND_CONF}.mk
	@${MKDIR} ${OBJECTDIR} 
	@${RM} ${OBJECTDIR}/buffer.o.d 
	@${RM} ${OBJECTDIR}/buffer.o 
	@${FIXDEPS} "${OBJECTDIR}/buffer.o.d" $(SILENT) -rsi ${MP_CC_DIR}../  -c ${MP_CPPC}  $(MP_EXTRA_CC_PRE)  -g -x c -c -mprocessor=$(MP_PROCESSOR_OPTION)  -MMD -MF "${OBJECTDIR}/buffer.o.d" -o ${OBJECTDIR}/buffer.o buffer.c   
	
endif



# ------------------------------------------------------------------------------------
# Rules for buildStep: compileCPP
ifeq ($(TYPE_IMAGE), DEBUG_RUN)
${OBJECTDIR}/main.o: main.cpp  nbproject/Makefile-${CND_CONF}.mk
	@${MKDIR} ${OBJECTDIR} 
	@${RM} ${OBJECTDIR}/main.o.d 
	@${RM} ${OBJECTDIR}/main.o 
	@${FIXDEPS} "${OBJECTDIR}/main.o.d" $(SILENT) -rsi ${MP_CC_DIR}../  -c ${MP_CPPC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist  -x c++ -c -mprocessor=$(MP_PROCESSOR_OPTION)  -frtti -fexceptions -fno-check-new -fenforce-eh-specs -MMD -MF "${OBJECTDIR}/main.o.d" -o ${OBJECTDIR}/main.o main.cpp  
	
${OBJECTDIR}/interrupt.o: interrupt.cpp  nbproject/Makefile-${CND_CONF}.mk
	@${MKDIR} ${OBJECTDIR} 
	@${RM} ${OBJECTDIR}/interrupt.o.d 
	@${RM} ${OBJECTDIR}/interrupt.o 
	@${FIXDEPS} "${OBJECTDIR}/interrupt.o.d" $(SILENT) -rsi ${MP_CC_DIR}../  -c ${MP_CPPC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist  -x c++ -c -mprocessor=$(MP_PROCESSOR_OPTION)  -frtti -fexceptions -fno-check-new -fenforce-eh-specs -MMD -MF "${OBJECTDIR}/interrupt.o.d" -o ${OBJECTDIR}/interrupt.o interrupt.cpp  
	
${OBJECTDIR}/buffer.o: buffer.cpp  nbproject/Makefile-${CND_CONF}.mk
	@${MKDIR} ${OBJECTDIR} 
	@${RM} ${OBJECTDIR}/buffer.o.d 
	@${RM} ${OBJECTDIR}/buffer.o 
	@${FIXDEPS} "${OBJECTDIR}/buffer.o.d" $(SILENT) -rsi ${MP_CC_DIR}../  -c ${MP_CPPC} $(MP_EXTRA_CC_PRE) -g -D__DEBUG -D__MPLAB_DEBUGGER_PK3=1 -fframe-base-loclist  -x c++ -c -mprocessor=$(MP_PROCESSOR_OPTION)  -frtti -fexceptions -fno-check-new -fenforce-eh-specs -MMD -MF "${OBJECTDIR}/buffer.o.d" -o ${OBJECTDIR}/buffer.o buffer.cpp  
	
else
${OBJECTDIR}/main.o: main.cpp  nbproject/Makefile-${CND_CONF}.mk
	@${MKDIR} ${OBJECTDIR} 
	@${RM} ${OBJECTDIR}/main.o.d 
	@${RM} ${OBJECTDIR}/main.o 
	@${FIXDEPS} "${OBJECTDIR}/main.o.d" $(SILENT) -rsi ${MP_CC_DIR}../  -c ${MP_CPPC} $(MP_EXTRA_CC_PRE)  -g -x c++ -c -mprocessor=$(MP_PROCESSOR_OPTION)  -frtti -fexceptions -fno-check-new -fenforce-eh-specs -MMD -MF "${OBJECTDIR}/main.o.d" -o ${OBJECTDIR}/main.o main.cpp  
	
${OBJECTDIR}/interrupt.o: interrupt.cpp  nbproject/Makefile-${CND_CONF}.mk
	@${MKDIR} ${OBJECTDIR} 
	@${RM} ${OBJECTDIR}/interrupt.o.d 
	@${RM} ${OBJECTDIR}/interrupt.o 
	@${FIXDEPS} "${OBJECTDIR}/interrupt.o.d" $(SILENT) -rsi ${MP_CC_DIR}../  -c ${MP_CPPC} $(MP_EXTRA_CC_PRE)  -g -x c++ -c -mprocessor=$(MP_PROCESSOR_OPTION)  -frtti -fexceptions -fno-check-new -fenforce-eh-specs -MMD -MF "${OBJECTDIR}/interrupt.o.d" -o ${OBJECTDIR}/interrupt.o interrupt.cpp  
	
${OBJECTDIR}/buffer.o: buffer.cpp  nbproject/Makefile-${CND_CONF}.mk
	@${MKDIR} ${OBJECTDIR} 
	@${RM} ${OBJECTDIR}/buffer.o.d 
	@${RM} ${OBJECTDIR}/buffer.o 
	@${FIXDEPS} "${OBJECTDIR}/buffer.o.d" $(SILENT) -rsi ${MP_CC_DIR}../  -c ${MP_CPPC} $(MP_EXTRA_CC_PRE)  -g -x c++ -c -mprocessor=$(MP_PROCESSOR_OPTION)  -frtti -fexceptions -fno-check-new -fenforce-eh-specs -MMD -MF "${OBJECTDIR}/buffer.o.d" -o ${OBJECTDIR}/buffer.o buffer.cpp  
	
endif

# ------------------------------------------------------------------------------------
# Rules for buildStep: link
ifeq ($(TYPE_IMAGE), DEBUG_RUN)
dist/${CND_CONF}/${IMAGE_TYPE}/testpic32.X.${IMAGE_TYPE}.${OUTPUT_SUFFIX}: ${OBJECTFILES}  nbproject/Makefile-${CND_CONF}.mk    
	@${MKDIR} dist/${CND_CONF}/${IMAGE_TYPE} 
	${MP_CPPC} $(MP_EXTRA_LD_PRE)  -mdebugger -D__MPLAB_DEBUGGER_PK3=1 -mprocessor=$(MP_PROCESSOR_OPTION)  -o dist/${CND_CONF}/${IMAGE_TYPE}/testpic32.X.${IMAGE_TYPE}.${OUTPUT_SUFFIX} ${OBJECTFILES_QUOTED_IF_SPACED}           -mreserve=data@0x0:0x1FC -mreserve=boot@0x1FC02000:0x1FC02FEF -mreserve=boot@0x1FC02000:0x1FC024FF  -Wl,--defsym=__MPLAB_BUILD=1$(MP_EXTRA_LD_POST)$(MP_LINKER_FILE_OPTION),--defsym=__MPLAB_DEBUG=1,--defsym=__DEBUG=1,--defsym=__MPLAB_DEBUGGER_PK3=1,-Map="${DISTDIR}/${PROJECTNAME}.${IMAGE_TYPE}.map"
	
else
dist/${CND_CONF}/${IMAGE_TYPE}/testpic32.X.${IMAGE_TYPE}.${OUTPUT_SUFFIX}: ${OBJECTFILES}  nbproject/Makefile-${CND_CONF}.mk   
	@${MKDIR} dist/${CND_CONF}/${IMAGE_TYPE} 
	${MP_CPPC} $(MP_EXTRA_LD_PRE)  -mprocessor=$(MP_PROCESSOR_OPTION)  -o dist/${CND_CONF}/${IMAGE_TYPE}/testpic32.X.${IMAGE_TYPE}.${DEBUGGABLE_SUFFIX} ${OBJECTFILES_QUOTED_IF_SPACED}          -Wl,--defsym=__MPLAB_BUILD=1$(MP_EXTRA_LD_POST)$(MP_LINKER_FILE_OPTION),-Map="${DISTDIR}/${PROJECTNAME}.${IMAGE_TYPE}.map"
	${MP_CC_DIR}\\xc32-bin2hex dist/${CND_CONF}/${IMAGE_TYPE}/testpic32.X.${IMAGE_TYPE}.${DEBUGGABLE_SUFFIX} 
endif


# Subprojects
.build-subprojects:


# Subprojects
.clean-subprojects:

# Clean Targets
.clean-conf: ${CLEAN_SUBPROJECTS}
	${RM} -r build/default
	${RM} -r dist/default

# Enable dependency checking
.dep.inc: .depcheck-impl

DEPFILES=$(shell mplabwildcard ${POSSIBLE_DEPFILES})
ifneq (${DEPFILES},)
include ${DEPFILES}
endif

The compiler found multiple definitions for the main function, even. Move all other source files away and try compiling again, it sounds like you're compiling two projects as if they're one.
> i thought that the inclusion guards are so posed to keep multiple definition issues from happening.
> that if BUFFER_H is already declared then don't declare it again resulting in a single definition of ring_buffer
> or does this only hold true for function prototypes?
Inclusion guards protects against redefinition, by instance a class (or struct) definition cannot appears twice for a single translation unit.

multiple definition means that two translations units cannot have each one a definition for a function.

You may declare things as many times as you want, there is no problem there.


> should i only include function prototypes and externrd variable is my header files?
class or struct definitions are fine too
Also, template and inline function definition must be in headers
do i understand this correctly

1
2
3
4
5
struct my_struct {
int stuff[4];
int high;
int low;
};


this is a declaration and i can declare this as may times as i want anywhere i want.

 
struct my_struct things_to_store;


is a definition and can only exist in one place. if i need to use it somewhere else i need to declare it extern?

struct my_struct things_to_store;
defining a variable

extern struct my_struct things_to_store;
declaring (it exist somewhere) a variable
one (and only one) translation unit ought to define it, or you'll get undefined reference errors.

struct foo;
(forward) declaring an struct

1
2
3
struct foo{
   int stuff[42];
};
defining an struct.
If in one file you've got
1
2
3
4
5
6
struct foo{
   int stuff[42];
};
struct foo{
   int stuff[42];
};
that would be a redefinition error.

However, as you can easily check with `nm', an struct does not become a symbol in an object file so you would not experience a multiple definition error.


To clarify, the struct `my_struct' does not become a symbol
but the global variable `things_to_store' yes, it does.
Last edited on
If :

file1.cpp compiles to file1.o
file2.cpp compiles to file2.o
file1.o + file2.o links to an executable file.exe

If file1.cpp and file2.cpp includes xyz.h which _declares_ a variable, then two instances of that variable will exist in the link, and the link will fail. This is the problem you have.

The guards are for _each_ of the compiles to avoid including files more than once.
So:

file.cpp includes a.h and b.h
a.h includes c.h
b.h includes c.h

Then a compile of file.cpp will include c.h twice. Having the guards around the real content of c.h will stop that content appearing twice in the one compile. Note that this is a preprocessor action.


Topic archived. No new replies allowed.