using ifdef

I am using preprocessor ifdef and endif for the first time and i am getting some
errors in vs2012 on windows 7 . Here is the code

//header file
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
  #include <tchar.h>
#include <iostream>
#include <conio.h>
#include <time.h>
#include <stdlib.h>

#ifdef _WIN32
    #include <windows.h>

    void sleep(unsigned milliseconds)
    {
        Sleep(milliseconds);
    }
#else
    #include <unistd.h>

    void sleep(unsigned milliseconds)
    {
        usleep(milliseconds * 1000); // takes microseconds
    }
#endif; 


//cpp file
1
2
3
4
5
6
7
8
9
10
11
12
#include "stdafx.h"

void main() {

	for(int i = 0;i<10;i ++){
		
		std::cout<<time(NULL)<<std::endl;
		sleep(5000);

}
	_getch();
}


the errors :
error LNK1169: one or more multiply defined symbols found
error LNK2005: "void __cdecl sleep(unsigned int)" (?sleep@@YAXI@Z) already defined in stdafx.obj

The microsoft site said:
The /FORCE or /FORCE:MULTIPLE option overrides this error.

Now where can i get/put this /FORCE option?

Thanks!!

The problem is that the sleep function is defined multiple times, once for each translation unit that includes the header. To solve this you can make the sleep function inline (because inline functions follow different rules) or move the definition of the function to a source file.
If i move the definitions to the source file, the following errors occur :


error C2084: function 'void sleep(unsigned int)' already has a body
error C3861: 'sleep': identifier not found



Making the function inline works,but what if in the future i dont want the function to be inline ?How can i solve this problem ? Is there a more elegant way to write this piece of code ,to make it compile on more than just windows .

Thanks

> How can i solve this problem ?

Use a namespace.

1
2
3
4
5
6
7
8
9
10
// header_file utils.h
#ifndef UTILS_H_INCLUDED
#define UTILS_H_INCLUDED

namespace utils 
{ 
    void sleep( unsigned int millisecs ) ;  
}

#endif // UTILS_H_INCLUDED 


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
// utils.cpp
#include "utils.h"

#ifdef LEGACY_CPLUSPLUS

    #ifdef _WIN32
        #include <Windows.h>
        namespace utils
        {
             void sleep( unsigned int millisecs ) { ::Sleep(millisecs) ; }
        }

    #else // !_WIN32
        #include <unistd.h> 
        namespace utils
        {
             void sleep( unsigned int millisecs ) { ::usleep( millisecs * 1000 ) ; }
        }
    #endif // _WIN32

#else // C++11
        #include <thread>
        #include <chrono>
        namespace utils
        {
            void sleep( unsigned int millisecs ) 
            { std::this_thread::sleep_for( std::chrono::milliseconds(millisecs) ) ; }
        }

#endif // LEGACY_CPLUSPLUS 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
// main.cpp
#include <iostream>
#include <ctime>
#include "utils.h"

int main()
{
    for( int i = 0 ; i < 3 ; ++i )
    {
        std::time_t now = time( nullptr ) ;
        std::cout << std::asctime( std::localtime(&now) ) << std::endl;
        utils::sleep( 2000 );
    }
}
Last edited on
Thanks !
Topic archived. No new replies allowed.