-3

Foo1.hpp:

#pragma once

#include <string>

enum class Foo1 {
   A, B, C
};

// Commented out to avoid compiler error
//inline Foo1 fFromStr(const std::string& a) {
//    if (a == "A") return Foo1::A;
//    if (a == "B") return Foo1::B;
//    else          return Foo1::C;
//}

inline std::string fToStr(const Foo1 a) {
    switch (a) {
    case Foo1::A: return "A";
    case Foo1::B: return "B";
    default     : return "C";
    }
}

Foo2.hpp:

#pragma once

#include <string>

enum class Foo2 {
   A, B, C
};

// Commented out to avoid compiler error
//inline Foo2 fFromStr(const std::string& a) {
//    if (a == "A") return Foo2::A;
//    if (a == "B") return Foo2::B;
//    else          return Foo2::C;
//}

inline std::string fToStr(const Foo2 a) {
    switch (a) {
    case Foo2::A: return "A";
    case Foo2::B: return "B";
    default     : return "C";
    }
}

main.cpp:

#include "Foo1.hpp"
#include "Foo2.hpp"

int main() {
    fToStr(Foo1::A);
    //fFromStr("A");
    fToStr(Foo2::A);
    //fFromStr("A");
    return 0;
}

From what I have read online two global inline functions must have unique names to avoid undefined behavior. I believe the undefined behavior would come from the linker arbitrarily choosing one of the functions and removing the other

In the code above the two fFromStr cause a compiler error because they are ambiguous:

In file included from main.cpp:2:
Foo2.hpp:9:13: error: ambiguating new declaration of 'Foo2 fFromStr(const string&)'
    9 | inline Foo2 fFromStr(const std::string& a) {
      |             ^~~~~~~~
In file included from main.cpp:1:
Foo1.hpp:9:13: note: old declaration 'Foo1 fFromStr(const string&)'
    9 | inline Foo1 fFromStr(const std::string& a) {
      |

However fToStr does not cause a compiler error because its usage requires specifying Foo1 or Foo2

My question is whether the two fToStr cause undefined behavior or if their type requirements avoid an issue

asimes
  • 5,749
  • 5
  • 39
  • 76
  • 1
    [Inline functions with same type but different body in .cpp files](https://stackoverflow.com/questions/64537486/inline-functions-with-same-type-but-different-body-in-cpp-files) – Jason May 03 '23 at 15:49
  • There can be more than one definition of a ... inline function ... Each such definition shall consist of the same sequence of tokens... – Jason May 03 '23 at 15:50
  • @Jason, your linked question is for two .cpp files rather than two header files – asimes May 03 '23 at 15:53
  • 1
    Header file and source files are just for convenience. The standard doesn't use those terms. The correct term is "translation unit" and the program has undefined behavior. – Jason May 03 '23 at 15:55
  • @Jason, In my question any file that includes both Foo1.hpp and Foo2.hpp will see the two `fToStr`. In your linked question each .cpp file will see its own `foo` method – asimes May 03 '23 at 15:57
  • @Jason, Additionally your linked question does not address whether or not different type arguments still cause undefined behavior – asimes May 03 '23 at 16:06
  • 3
    The two versions of `fToStr` have different argument lists, so they are not the same function. `inline` and overloading are independent of each other. – Pete Becker May 03 '23 at 16:14

1 Answers1

5

whether the two fToStr cause undefined behavior or if their type requirements avoid an issue

inline std::string fToStr(const Foo1 a)
inline std::string fToStr(const Foo2 a)

These are just bog-standard run-of-the-mill overloaded functions. There is nothing wrong with them whatsoever.

n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243