0

I 'am running my first C++ project using Visual Studio 2012 This is the architecture of my project:

Source Files 
 |main.cpp
 |stdafx.cpp
 |module.cpp
Header files
 |stdafx.h
 |targetver.h 
 |module.h

I always try to be modular in my code so i usually decalare variables and structures in the .h and then define them on the cpp files

//module.h
#ifndef MODULE_H
#define MODULE_H

int a;
typedef struct 
{
 int a;
 int b;
}tmastruct;
typedef enum {LUNDI, MARDI}eMaEnum;
extern void fct(void);

#endif 

module.cpp:

//module.cpp
#include "stdafx.h"
#include "a.h"

void fct()
{
  printf ("Hello World \n");
}

but actually i don't know why i get

error LNK2005: "int a" (?a@@3IA) main.obj  

i know that by declaring a as extern int a the problem will be resolved but i wonder why the first declaration works on a c project and not in a c++ project

i also have a question about using stdAfx.h the proper way after checking some posts i make the following rule:

1) stdafx.h should contain the headers that are rarely modified (it means it shouldn't contain the header of your own modules)

2) stdafx.h should be included only in the .cpp files after including stdafx.h you may include your own modules header

do you think that this rule is right and what do you do to handle your modules?

fedi
  • 368
  • 3
  • 7
  • 18

1 Answers1

0

As Olaf says, C and C++ are very different languages, but to that I add that MSVC (and GCC) are unique things unto themselves beyond both.

It is a bad idea to define data elements such as int a in a header because if the header gets included more than once, it results in multiple definitions, which is undefined behavior in C and ill-formed (no-diagnostic-required) in C++. MSVC may be one of the compilers that accepts multiple common non-conflicting definitions in C as an extension but apparently, as is not unusual, it diagnoses and doesn't accept it in C++.

See this answer on Tentative definitions in C99 and linking, it is my read that MSVC shouldn't accept this program, even in C.

Note: there isn't quite enough detail to duplicate here to be certain

To your question, the best suggestions I have:

  • Put declarations of data items in the module headers, always with extern
  • Put declarations of functions in the module headers, extern is superflous so be consistent, but either way it is the same
  • Do not put anything in stdafx.h except what the GUI thing does automatically or requires
  • stdafx.h must be first in all .cpp files that use it, followed by other headers
  • Separate portable C or C++ code away from MSVC specific code and do not include stdafx.h in those files. This may even be a separate static or dynamic library.
Community
  • 1
  • 1
Anders
  • 2,270
  • 11
  • 19
  • Thanks Anders, your answer help me undrestand some bad habit i usually use in my code , i just didn't undrestand the 5th point what i know (and as you have mentioned in point 4) including stdafx.h is mandatory in all cpp/c file. – fedi Dec 15 '15 at 20:10
  • No, certainly stdafx.h is not required for non-Windows C or C++ code. And it should not be included in such code. But if precompiled headers is enabled or MFC is in use, all .cpp files in the main .exe project need it. So one thing you can do is to move, what is usually the majority of the code, portable ANSI C or C++ to a static library or DLL project. Remember, you MSVC has extensions to standard C, but you can still write standard C code too if you work at it. And stdafx.h is not standard at all; it isn't even a good practice to copy putting all your .h in a common one like that. – Anders Dec 16 '15 at 03:12
  • When I say non-windows, I still mean code running on Windows compiled by MSVC. For example, `fopen` vs. `CreateFile` - the later is a Windows API and requires stdafx.h (or Windows.h) and the former does *not*. It would require `stdio.h` only. – Anders Dec 16 '15 at 03:15