2

It is convenient to use unique error codes that the user will see on an error. This will make it easier to locate the origin of the error for the developer (just do a search in the source code for the error code), thus saving time.

Example:

void f()
{
  std::cout << "UNIQUE001 " << "Error : The query failed" << std::endl;
}

void g()
{
  f();
}

int main()
{
  g();
  return 0;
}

In the example, the user reports the error ("UNIQUE001 Error : The query failed"). The developer just does a project-wide search on "UNIQUE001", and immediately finds where the error was thrown. (A file with line number does not suffice, as the code might have changed in the meantime).

So, to the question : Is there a way to enforce the uniqueness of the error code strings at compile-time (ideally, with either preprocessor macros or TMP) or at run-time (e.g. in a unit test)?

UPDATE

My best attempt so far has been to make a struct with a macro, that creates a type with a value string equal to the type name and error code. This works and gives a compile time error for duplicate types, but structs can't be declared everywhere (e.g. in an expression)

#define generateerrorcode(code) \
struct code \
{ \
  static const char* value = #code \
}; \

I'd like to be able to use unique-checking functionality like this, if possible:

void some_function()
{
  std::cout << check_unique("UNIQUE001") << "Error : The query failed" << std::endl;
}
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
meastp
  • 682
  • 1
  • 7
  • 15
  • Relevant: [Making code findable by using globally unique message IDs](https://softwareengineering.stackexchange.com/questions/364918/making-code-findable-by-using-globally-unique-message-ids) – John Wu May 09 '18 at 16:36

2 Answers2

1

If you want to be 100% sure, you can use GUID and one of many millions of generators that are out there.

Caesar
  • 9,483
  • 8
  • 40
  • 66
  • 5
    @K-ballo The day you generate 2 GUID that are the same, is the day I edit the post. – Caesar Jan 05 '13 at 20:39
  • 2
    True, but that doesn't make your answer any more right. The uniqueness of a _GUID_ is not _enforced_ at all, as the OP requests. – K-ballo Jan 05 '13 at 20:42
  • 1
    @K-ballo Any enforcement of unique identifiers has a much higher chance or failing (bug in the build step that checks this; human error in the *process* that should ensure uniqueness; you name it) than the UUIDs have a chance of colliding. So in that sense, UUIDs are more right w.r.t. uniqueness. All assuming you use the right UUID version (v4, random). –  Jan 05 '13 at 20:49
  • It would require a GUID-generator. I'd like to be able to make up an error code in my mind, and have it checked either at compile-time, or in a unit test, making it as simple as possible to use... :) – meastp Jan 05 '13 at 21:01
  • @meastp I give you a link to an on-line generator, a C++ library that does it in my post, and how you can get it in VS2010 if your using that. But there are hundreds of those generators out there so feel free to pick one. – Caesar Jan 05 '13 at 21:02
  • 1
    GUID's are more than unique enough- it might not be technically enforced, but realistically, it's quite unique. – Puppy Jan 05 '13 at 21:05
  • Yes. The current practice is to have a text-document and append a new error code to this every time a new error code is required. This would not be a considerable improvement, I'm afraid. Still, it is a viable option, and could contain extra information in the guid :) – meastp Jan 05 '13 at 21:10
  • I agree that GUIDs are a good solution as far as *uniqueness*, but the OP mentioned that the "user reports the error." The drawback to GUIDs is that they're unwieldy to recite over the phone to tech support ("LNK2001" rather than "E4C21F9A-7037-4EFE-B250-02F511D5A659"). You can encode the GUID with a larger character set, but it still ends up being 20+ bytes depending on what is used, and you have to be careful about confusing "1" with lowercase "l", "0" with "O," and maybe try to minimize characters that sound alike as well ("N" and "M," for instance). It remains a curiously good question. – Dave Ruske Apr 10 '17 at 01:46
0

You say:

(A file with line number does not suffice, as the code might have changed in the meantime).

But what if you will not wtire it your self but compiler will? i.e __FILE__, __LINE__, __FUNCTION__. See: __FILE__, __LINE__, and __FUNCTION__ usage in C++

However, it'll fail if code was changed after error but before you'll fix it. (But you may see edit history)

Community
  • 1
  • 1
RiaD
  • 46,822
  • 11
  • 79
  • 123
  • This question is tagged _C++_, and there a standard compliant implementation could choose to emit an empty string for every use of `__FUNCTION__`. And it still doesn't work if your code has moved around, renamed, refactored, etc... – K-ballo Jan 05 '13 at 20:44
  • @K-ballo, I've added when it may fail. But it seems not so critical because, after editing it'll correct again. And if you know time when error occurred and history of the code, you'll succeed. – RiaD Jan 05 '13 at 20:54