I am in the process of creating a C wrapper around a C++ library.
One common mistake to make while doing this is having a function declaration and definition that do not match for some reason (typo, renames, argument got added/removed, etc).
For example:
// enabledata.h
MDS_C_API const char* motek_mds_enable_data_get_enable_command_name();
// enabledata.cpp
const char* motek_mds_enable_data_enable_command_name() { ... }
The names do not match, but because of the lack of scope for these functions, it will not result in any compile errors, and will only show up much later down the line as a link error.
I want the compiler to help me find these errors by using the global scope operator like so:
const char* ::motek_mds_enable_data_get_disable_command_name() { ... }
This will now show up as a compile error if the function has not been declared yet, which is exactly what I want.
However, this does not work when the function returns a typedef:
int32_t ::motek_mds_enable_data_is_enabled(const Data* a_Data) { ... }
This will result in an attempt to use int32_t as a scope, which of course results in an error:
left of '::' must be a class/struct/union
Are there any ways to make this work? Better alternatives are also welcome of course.
I am currently using Visual Studio 2015 Update 2.
You can always parenthesize the declarator-id:
int32_t (::motek_mds_enable_data_is_enabled)(const Data* a_Data) { ... }
// ^ ^
Related
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:
The solution needs to be a fixed piece of code I paste into my own code where I want to check what the namespace is, and possibly additional compiler flags to use.
The solution should work for as many of: gcc, clang, nvcc, msvc, icc as possible. I particularly care about nvcc (the CUDA compiler) and gcc.
I'd prefer the least amount of "noise" possible other than the namespace and some "marker text" I'll look for in the output.
Somewhat related question: How to get string for current namespace in Macro
This will depend on compilers and their versions. One that currently works for all gcc, clang, icc and msvc (let us know if it works for nvcc!) is accessing a missing data member:
struct A { A() { this->a; } };
All compilers will report an error with the qualified name, e.g.:
error: no member named 'a' in 'foo::bar::A'
So you can easily grep for ::A' or ::A" and extract it (all those 4 major compilers put the name between quotes; otherwise, simply use a unique identifier that you won't find anywhere else etc.).
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
}
The following sketch to fails to compile in the Arduino environment.
Given that typedefs can be used within Arduino software, is Automatic Prototype Generation the underlying mechanism that causes the failure? If so, what is it and why isn't Arduino providing a lightweight wrapper around C++?
#define PRODUCE_WACKY_COMPILETIME_ERROR
typedef int MyMeaningfulType;
#ifndef PRODUCE_WACKY_COMPILETIME_ERROR
void myFunc(MyMeaningfulType myParam);
#endif
void myFunc(MyMeaningfulType myParam)
{
myFunc(10);
}
void setup() {}
void loop() {}
For the benefit of the search engines, the errors reported are:
error: variable or field 'myFunc' declared void
error: 'MyMeaningfulType' was not declared in this scope
Please refer to http://arduino.cc/en/Hacking/BuildProcess the specific quote is:
This means that if you want to use a custom type as a function argument, you should declare it within a separate header file.
This page does a good job of explaining how the Arduino Language is different from C/C++ in how it works/pre-processes files.
They are attempting to create prototypes for every function they find. Unfortunately, if you define a typedef in the file before the function, and use that in a function definition, the place they put the function prototype does not see it, and this generates a syntax error.
If you use the 'struct * ' syntax instead in those function definitions, you benefit from C's 'opaque type' facility, in which you can use a struct definition without having it be declared beforehand. So, build the typedef, use it, but use the struct definition in any functions that use the typedef in arguments.
typedef struct mytype_ {
int f1;
} mytype_t;
void myfunc(struct mytype_ * xxx) {
xxx->f1 = 1;
}
So I'm playing around with stacks and I've filled one in my main function, but now I want to pass it to my other functions so I can traverse through it. I'm not sure what kind of data type to put into the prototype though so that it accepts it. Suggestions? Here's what I have:
Main.cpp
#include <iostream>
using namespace std;
#include "stack.h"
void displayStack(char &stackRef);
int main()
{
Stack<char> stack;
stack.push('a');
stack.push('b');
stack.push('c');
return 0;
};
void displayStack(char starRef)
{
// Cannot Get here - Errors!
};
It's telling me I have too many arguments and it doesn't match argument list.
This should suffice:
void displayStack(const Stack<char>& stack);
The name DisplayStack indicates that the function only displays the stack, not changing it in any way. So then the argument can be a reference to const. However, the suffix Stack in the name is redundant since it is implied by the argument, so I’d do it like this:
#include <iostream>
using namespace std;
#include "stack.h"
typedef Stack< char > CharStack;
void display( CharStack const& stack )
{
// ... Display the stack
}
int main()
{
CharStack stack;
for( auto const ch : { 'a', 'b', 'c' } )
{
stack.push( ch );
}
display( stack );
}
Note that …
The function has been moved above main. No silly pure declaration required then, less work. DRY: Don't Repeat Yourself.
Incorrect semicolons after the function definitions, have been removed. Well, at least I think they’re incorrect. Whether they are or not, they’re totally superfluous.
Superfluous return 0; in main has been removed, because that is the default. However, some programmers prefer to have it explicit.
On the downside, while the C++11 loop compiles nicely with g++ 4.7.2, it causes an Internal Compiler Error (ICE) with Visual C++ 11.0:
[d:\dev\test]
> cl foo.cpp
foo.cpp
foo.cpp(7) : warning C4100: 'stack' : unreferenced formal parameter
foo.cpp(16) : error C2059: syntax error : '{'
foo.cpp(16) : error C2143: syntax error : missing ';' before '}'
c1xx : fatal error C1063: INTERNAL COMPILER ERROR
Please choose the Technical Support command on the Visual C++
Help menu, or open the Technical Support help file for more information
[d:\dev\test]
> _
Oh well.
Do that your way. ;-)
Compiler bug reported to Microsoft.
If you do not want to modify contents of the stack inside the function:
void displayStack(const Stack<char> &starRef)
If you want to modify the contents of the stack inside the function:
void displayStack(Stack<char> &starRef)
Points to note:
The type of the variable being passed must be the type you mention in function prototype.
In C/C++, by default all arguments to function are passed by copy, i.e: A copy of the argument rather than the argument itself is passed to the function. The overhead is the copy. You pass by reference to avoid overhead of a copy of variable being passed.
You use const qualifier on the argument if you want the passed variable to be immutable in the function.
Change your displayStack function to:
void displayStack(Stack<char> &stackRef)
Below are two simplified code examples: the first one compiles just fine, the second one emits a compile error (no operator << found which takes a left hand operator ByteVector...).
The only difference in between the two examples is the placement of the using directive.
I don't want to know why it fails (you got not enough information to answer this), I am only interested in why it does make any difference where I place the using.
I would have expected the exact same behaviour in both examples.
Compiles without error
ByteVector Test()
{
using Base::operator <<;
ByteVector foo;
int bar = 1;
foo << bar;
return foo;
}
Compiles with error
using Base::operator <<;
ByteVector Test()
{
...same as above, without using
}
Extra information:
The operator<< used is defined as follows
template<typename T>
ByteVector& operator<<(ByteVector &, const T&){...};
The only thing that comes to my mind is Visual Studio. If that was the case, you may want to put the using directive right after the corresponding #include. As the remark on the page says:
Putt your using directive at the beginning of the source code file to
reduce the potential for unexpected behavior with IntelliSense.
Otherwise, it shouldn't make any difference.
Is there any way to check if a given function is declared with C-linkage (that is, with extern "C") at compile-time?
I am developing a plugin system. Each plugin can supply factory functions to the plugin-loading code. However, this has to be done via name (and subsequent use of GetProcAddress or dlsym). This requires that the functions be declared with C-linkage so as to prevent name-mangling. It would be nice to be able to throw a compiler error if the referred-to function is declared with C++-linkage (as opposed to finding out at runtime when a function with that name does not exist).
Here's a simplified example of what I mean:
extern "C" void my_func()
{
}
void my_other_func()
{
}
// Replace this struct with one that actually works
template<typename T>
struct is_c_linkage
{
static const bool value = true;
};
template<typename T>
void assertCLinkage(T *func)
{
static_assert(is_c_linkage<T>::value, "Supplied function does not have C-linkage");
}
int main()
{
assertCLinkage(my_func); // Should compile
assertCLinkage(my_other_func); // Should NOT compile
}
Is there a possible implementation of is_c_linkage that would throw a compiler error for the second function, but not the first? I'm not sure that it's possible (though it may exist as a compiler extension, which I'd still like to know of). Thanks.
I agree with Jonathan Leffler that this probably is not possible in a standard way. Maybe it would be possible somewhat, depending on the compiler and even version of the compiler, but you would have to experiment to determine possible approaches and accept the fact that the compiler's behavior was likely unintentional and might be "fixed" in later versions.
With g++ version 4.4.4 on Debian Squeeze, for example, you might be able to raise a compiler error for functions that are not stdcall with this approach:
void my_func() __attribute__((stdcall));
void my_func() { }
void my_other_func() { }
template <typename ret_, typename... args_>
struct stdcall_fun_t
{
typedef ret_ (*type)(args_...) __attribute__((stdcall));
};
int main()
{
stdcall_fun_t<void>::type pFn(&my_func),
pFn2(&my_other_func);
}
g++ -std=c++0x fails to compile this code because:
SO2936360.cpp:17: error: invalid conversion from ‘void ()()’ to ‘void ()()’
Line 17 is the declaration of pFn2. If I get rid of this declaration, then compilation succeeds.
Unfortunately, this technique does not work with cdecl.
For Unix/Linux, how about analyzing the resulting binary with 'nm' and looking for symbol names? I suppose it's not what you meant, but still it's sort of compile time.