0

I'm getting the following error when trying to build and run my C++ Project:

||=== Build: Debug in CS II (compiler: GNU GCC Compiler) ===|

obj\Debug\main.o||In function 'main':|
|30|undefined reference to '(anonymous namespace)::deleteRepeats(char*)'||

|error: ld returned 1 exit status|
||=== Build failed: 2 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|

My code is as follows for each file (I wouldn't be surprised if a lot is buggy or just plain wrong, as I haven't been able to test it at all and my focus has been on remedying that):

main.cpp:

#include <iostream>
#include "implementation.hpp"

int main()
{
    char originalArray[SIZE];
    originalArray[0] = 'a';
    originalArray[1] = 'b';
    originalArray[2] = 'b';
    originalArray[3] = 'c';
    originalArray[4] = 'a';
    originalArray[5] = 'c';
    originalArray[6] = 'a';
    originalArray[7] = 'c';
    originalArray[8] = 'b';
    originalArray[9] = 'c';
    char *noRepeats;
    noRepeats = deleteRepeats(&(originalArray[0]));
    std::cout << noRepeats;
    return 0;

}

implementation.hpp:

#ifndef IMPLEMENTATION_HPP
#define IMPLEMENTATION_HPP
namespace
{
    const int SIZE = 10;
    char* deleteRepeats(char*);
}
#endif

implementation.cpp:

#include "implementation.hpp"

char* deleteRepeats(char* array_to_edit)
{
    char new_array[SIZE];
    int num_of_unique_letters_seen = 0;
    for (int letter = 0; letter < SIZE; letter++)
    {
        bool already_exists = false;
        for (int letter_seen = 0; letter_seen < num_of_unique_letters_seen; letter_seen++)
        {
            if (array_to_edit[letter] == new_array[letter_seen])
            {
                already_exists = true;
            }
        }
        if (!already_exists)
        {
            new_array[num_of_unique_letters_seen] = array_to_edit[letter];
            num_of_unique_letters_seen++;
        }
    }
    return &new_array[0];
}

I was prompted to ask this question in the comments of the answer to this question, which is very similar, but the accepted answer was already completed in my project when the issue arose.

Code where the namespace is given a name:

main.cpp:

#include <iostream>
#include "implementation.hpp"

int main()
{
    char originalArray[dts::SIZE];
    originalArray[0] = 'a';
    originalArray[1] = 'b';
    originalArray[2] = 'b';
    originalArray[3] = 'c';
    originalArray[4] = 'a';
    originalArray[5] = 'c';
    originalArray[6] = 'a';
    originalArray[7] = 'c';
    originalArray[8] = 'b';
    originalArray[9] = 'c';
    char *noRepeats;
    noRepeats = dts::deleteRepeats(&(originalArray[0]));
    std::cout << noRepeats;
    return 0;

}

implementation.cpp:

#include "implementation.hpp"

char* deleteRepeats(char* array_to_edit)
{
    char new_array[dts::SIZE];
    int num_of_unique_letters_seen = 0;
    for (int letter = 0; letter < dts::SIZE; letter++)
    {
        bool already_exists = false;
        for (int letter_seen = 0; letter_seen < num_of_unique_letters_seen; letter_seen++)
        {
            if (array_to_edit[letter] == new_array[letter_seen])
            {
                already_exists = true;
            }
        }
        if (!already_exists)
        {
            new_array[num_of_unique_letters_seen] = array_to_edit[letter];
            num_of_unique_letters_seen++;
        }
    }
    for (int letter = 0; letter < dts::SIZE; letter++)
    {
        array_to_edit[letter] = new_array[letter];
    }
    return array_to_edit;
}

implementation.hpp:

#ifndef IMPLEMENTATION_HPP
#define IMPLEMENTATION_HPP
namespace dts
{
    const int SIZE = 10;
    char* deleteRepeats(char*);
}
#endif
21
  • 3
    Why do you use namespace? Commented Sep 11, 2023 at 22:20
  • 6
    But anonymous namespaces hide names. Commented Sep 11, 2023 at 22:21
  • 1
    No, show the code, not a screenshot of it. Commented Sep 11, 2023 at 22:24
  • 1
    @FrasherGray Your question looks the same as this one. Are you both taking the same course? Commented Sep 11, 2023 at 22:27
  • 3
    You need to put the same namespace around your function in the .cpp file Commented Sep 11, 2023 at 22:33

2 Answers 2

1

The idea of a namespace is to resolve conflicts if e.g. functions happen to have the same name. Kind of like surnames for people, to tell John Bakerson and John Miller apart from each other.

So one John lives in the namespace Bakerson and the other in namespace Miller.

If you use namespaces, always tell the compiler which namespace your function belongs to.

// .hpp

namespace Bakerson {
  void John();
}

namespace Miller {
  void John();
}

// .cpp

namespace Bakerson {
  void John(){
    std::cout << "I'm John Bakerson.\n";
  }
}

namespace Miller {
  void John(){
    std::cout << "I'm John Miller.\n";
  }
}
Sign up to request clarification or add additional context in comments.

Comments

0

A functon declared in an unnamed namespace has internal linkage. So you need to define it in each compilation unit.

Otherwise declare it in a named namespace.

From the C++17 Standard (6.5 Program and linkage)

4 An unnamed namespace or a namespace declared directly or indirectly within an unnamed namespace has internal linkage. All other namespaces have external linkage. A name having namespace scope that has not been given internal linkage above has the same linkage as the enclosing namespace if it is the name of

//... (4.2) — a function; or

Also pay attention to that you placed the function definition in the global namespace but declared in the enclosed unnamed namespace.

And one more remark. The first your function definition is invald.

char* deleteRepeats(char* array_to_edit)
{
    char new_array[SIZE];

    //...
    return &new_array[0];
}

You are returning a pointer to a local array that will not be alive after exiting the function. Dereferencing such a pointer invokes undefined behavior.

Alsp this statement

std::cout << noRepeats;

also invokes undefined behavior because the array does not comntain a string.

Your approach with an auxiliary array is ineffcent and even wrong. This for loop

for (int letter = 0; letter < dts::SIZE; letter++)
{
    array_to_edit[letter] = new_array[letter];
}

fills the array array_to_edit not only with unique letters due to the conditon of the loop letter < dts::SIZE.

The function should deal with strings.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.