I'm trying to figure where in a bunch of code I'm missing a closing-brace for a namespace (i.e. getting a:
At end of source: error: expected a "}"
error). Maybe there are smarter ways to go about it, but - I want to try and check, at different points in my code, what the current namespace is. I don't need a macro; and I don't need a string; and I don't need something that will exist at run-time. I just want to get the compiler to somehow print the namespace. It's fine by me if it's in an #error
, a #warning
, or some construct which, failing to compile, produces an error with the namespace in it.
Example I want to generalize:
namespace ns1 { }
namespace ns2 {
namespace ns3 {
// MAGIC GOES HERE
}
this source file is missing a }
somewhere. But - did I forget to close ns1? Or maybe ns2? I don't remember - they are far away from the line I'm interested in. So I want to insert something magical, that will tell me what namespace I'm in right now. Well, for this example, I can write:
namespace ns1 { }
namespace ns2 {
namespace ns3 {
void ns_detector() { return 0; }
}
and with GCC 6.3, get the error:
b.cpp: In function ‘void ns2::ns3::ns_detector()’:
b.cpp:5:29: error: return-statement with a value, in function returning 'void' [-fpermissive]
void ns_detector() { return 0; }
^
b.cpp: At global scope:
b.cpp:7:1: error: expected ‘}’ at end of input
}
^
The first line of that error tells me what I need to know: It's ns2 that hasn't been closed. But - this is not so reliable. For longer, more complex pieces of code, that I compile with nvcc, using the "ns detector" function only gives me something like:
/path/to/file.cu(135): error: return value type does not match the function type
At end of source: error: expected a "}"
So, I need something more robust.
Notes:
A (possible) improvement on @Acorn's good and simple solution, which can be used many times, for detection in multiple places in the same file:
#define CONCATENATE(s1, s2) s1##s2
#define EXPAND_THEN_CONCATENATE(s1, s2) CONCATENATE(s1, s2)
#define UNIQUE_IDENTIFIER(prefix) EXPAND_THEN_CONCATENATE(prefix, __LINE__)
#define DETECT_NAMESPACE \
struct UNIQUE_IDENTIFIER(namespace_detector_on_line_) { \
void f() { look_at_the_class_name_above = 0; } \
};
Now you should be able to write DETECT_NAMESPACE on many different lines. Also, the macro definitions can be placed in a separate file.
For the code in the example, this will give:
b.cpp: In member function ‘void ns2::ns3::namespace_detector_on_line_13::f()’:
b.cpp:5:93: error: ‘look_at_the_class_name_above’ was not declared in this scope
#define DETECT_NAMESPACE struct UNIQUE_IDENTIFIER(namespace_detector_on_line_) { void f() { look_at_the_class_name_above! = 0; } };
^
b.cpp:13:1: note: in expansion of macro ‘DETECT_NAMESPACE’
DETECT_NAMESPACE
^~~~~~~~~~~~~~~~
b.cpp: At global scope:
b.cpp:15:1: error: expected ‘}’ at end of input
}