0

main cpp

#include "utility.h"
#include <windows.h>

int main()
{ 
    do
    {
        changeColor();
        system("pause");
    } while (true);
}

utility cpp

#include "utility.h"
#include "variables.h"
#include <windows.h>

namespace utility
{
    void changeColor()
    {
        if (var::colorCounter == 0)
        {
            system("color af");
        }
        else if (var::colorCounter == 1)
        {
            system("color cf");
        }
        else if (var::colorCounter == 2)
        {
            system("color df");
        }
        else if (var::colorCounter == 3)
        {
            system("color 6f");
        }
        else
        {
            system("color 9f");
            var::colorCounter = -1;
        }

        var::colorCounter++;
    }
}

utility header

#ifndef utility

#define utility

void changeColor();

#endif

variables

#ifndef variables
#define variables

namespace var
{
    inline int colorCounter{};
}

#endif

idk whats causing it to produce the changeColor() to not define what should i do? also is may coding right?

Chris
  • 26,361
  • 5
  • 21
  • 42
  • 2
    `changeColor` is declared in the global namespace but defined in the `utility` namespace – Alan Birtles Jan 24 '22 at 06:36
  • In C++ symbols can be *declared* or *defined*. In your case the function `changeColor` is *declared* in the `utility.h` header file, and *defined* (implemented) in the `utility.cpp` source file. To get the definition (implementation) you need to build with all source files. – Some programmer dude Jan 24 '22 at 06:39
  • This is also a good time to learn about the concept of [*translation units*](https://en.wikipedia.org/wiki/Translation_unit_(programming)) which is what the compiler really works with. In short, a translation unit is a single source file with all included header files. From a single translation unit the compiler will create an *object file* which is passed to the *linker* which takes all object files of your project, and links them together with libraries to create the actual executable program file. – Some programmer dude Jan 24 '22 at 06:41
  • Please include details on how you're building your program. It would help to ensure you're properly linking. – Chris Jan 24 '22 at 06:44
  • 1
    And as mentioned, the `changeColor` function declaration and definition are in two different namespaces. – Some programmer dude Jan 24 '22 at 06:44
  • @Someprogrammerdude build with all source file? how would i do that in vscode? – wertyuiop Jan 24 '22 at 06:59
  • [Using GCC with MinGW](https://code.visualstudio.com/docs/cpp/config-mingw). You need to create (or modify) a `tasks.json` file. I also recommend build-systems like Make or similar (or meta-build systems like [CMake](https://cmake.org)) to help you with multi-file projects. – Some programmer dude Jan 24 '22 at 07:07

1 Answers1

0

There are many problems with your code which are shown through the comments in the modified program below.

main.cpp

#include "utility.h"
int main()

{
        utility::changeColor();//used utility:: because you've to be in the scope of namespace utility to call function changeColor()
}

utility.h

#ifndef UTILITY_H  //USED INCLUDE GUARDS
#define UTILITY_H 

namespace utility {
void changeColor(); //this function declaration is now inside the utitliy namespace

}
#endif


variables.h

#ifndef VARIABLES_H //USED INCLUDE GUARDS
#define VARIABLES_H

namespace var
{
    //NOTE the extern keyword here instead of inline keyword
    extern int colorCounter; //this is a nondefininig declaraiton for colorCounter. 

}

#endif

variables.cpp

#include "variables.h"

namespace var 
{
    int colorCounter = 0; //this is definition of colorCounter
}

The output of the above program can be seen here.

Modifications

Some of the modifications that i made include:

  1. In main.cpp, you have to be in the scope of the namespace utility to call function changeColor(). This is achieved using utility::.
  2. In utility.h, header guards are used. This is a recommended practice.
  3. In utility.h, the function declaration for changeColor is placed inside the namespace utility.
  4. In variables.h, extern keyword is used instead of inline keyword to make the declaration of colorCounter a declaration that is not a definition. This essentially means, colorCounter has external linkage.
  5. In variables.cpp, the variable colorCounter has been initialized with value 0.

Note

If you still want to use inline instead of extern you can do so from C++17 and onward as can be seen here. So if you use inline your program will work for C++17 and onwards. But if you use extern as in my above code, then your program will work in all C++ versions. You can choose whichever version you want.

Jason
  • 36,170
  • 5
  • 26
  • 60
  • I believe inline variable also works. – apple apple Jan 24 '22 at 07:11
  • @appleapple Yes `inline` variable also works(from C++17 onwards) as can be seen [here](https://onlinegdb.com/yt-lMG0U9). – Jason Jan 24 '22 at 07:16
  • well I mean you don't need to modify that part of OP's code. (and the include guard for it also looks off) – apple apple Jan 24 '22 at 07:17
  • @appleapple I have added a note at the end of my answer mentioning that if you use `inline` instead of `extern` then your code will work with C++17 and onward. And if you use `extern` instead of `inline` then your code will work with all C++ versions. So you can choose accordingly. This way OP will get familiar with the traditional method(using `extern`) as well. – Jason Jan 24 '22 at 07:24
  • @AnoopRana hey why the namespace should be the same name? cuz i just found another prob that got me stuck is that in my source file and header doesnt have the same namespace name, so ill just ask why it needs to be the same? – wertyuiop Jan 26 '22 at 06:46
  • @wertyuiop In your original code, inside `utility.cpp` you have **defined** the function `changeColor` inside the namespace `utility`. But inside `utility.h` you have **declared** the function `changeColor` in *global namespace*. Now, inside `main.cpp` when you called the function by writing: `changeColor();` this means compiler will look for a function `changeColor` in the global namespace. But since you have **defined** the function `changeColor` in `utility`namespace inside `utility.cpp` instead of global namespace this gives you the error you mentioned in your original question. – Jason Jan 26 '22 at 06:56
  • @wertyuiop Continued.. This is the reason you need to put the **declaration** of the function `changeColor` in `utility.h` inside the `utility` namespace. Next, when i wrote: `utility::changeColor();` this means that we are now looking for a function named `changeColor` inside the `utility` namespace instead of global namespace. And now since we already have the declaration as well as definition for `changeColor` inside `utility` namespace, this call works. – Jason Jan 26 '22 at 07:00