I have a function as
AddSprintf(char* , ... )
I want to make compile time error if somebody is calling it without two arguments.
Currently if somebody is calling like
AddSprintf("hello")
it works. But I want to disable calling like this.
Is there any way using g++ I can force passing of argument ?
Overload AddSprintf:
void AddSprintf(const char* , ... ) {}
void AddSprintf(const char*);
Then you get a weird error message when compiling AddSprintf("hello")
But keep in mind that with C++11 you should use variadic templates because they are typesafe.
What about
AddSprintf(char* , char*, ... )
?
You can't, really. The dots stand for "zero or more arguments", and there is no way of knowing if there is any arguments. Except maybe using assembler and do some checking of the stack pointer.
As 0A0D says, it's variadic - by definition, the compiler is going to be fine with it. If you want it to fail at compiler time, you may have to pull tricks - for example, if you're unit testing, have code that makes the function fail with one argument call, so that new programmers will know they can't do that.
That said, why are you trying to do this? There may be a better solution to your problem.
If you want to stick to the same name, then you can use variadic macro:
#define AddSprintf(X,...) AddSprintf(X,__VA_ARGS__)
But be very careful with this solution, as AddSprintf would work first as text replacement in preprocessing stage. Then only it would be a function.
Related
I have an old C++ code that has this line of code:
int logprintf( const char* ptr, ... );
and I am not sure what does it do exactly? should I change the code in order to be able to compile the code with new versions of the compiler?! does anybody have an idea? any help would be appreciated.
That's just C code and any compiler made since the 1980s should be able to handle it. The definition is of a varidic function, or "varargs" in C parlance.
What that does is declare a method signature, nothing more. Presumably somewhere else, either in a library you link in or in a C or C++ file you compile there's a matching implementation.
Most printf-style functions do not have a fixed number of arguments. This is what the ellipsis ... represents, zero or more arbitrary arguments go there.
How would I declare a semantic action that calls a free function that doesn't use the attribute the rule/parser returned?
Like, let's say we have a parser that returns a string, but I want to call an unrelated function like Beep, which takes two integer values for frequency and duration and does not care for strings?
Is it actually possible to call it directly, or do I always have to write a proxy function which consumes the string and calls, in this case, Beep in it's body?
Edit:
My apologies.
I should have mentioned that I used boost::phoenix::bind at first with the syntax Hartmut suggested, which gave me this error:
could not deduce template argument for 'RT (__cdecl *)(T0,T1)' from 'BOOL (__stdcall *)(DWORD,DWORD)'
Is it the calling convention that messes things up here?
Edit2:
Seems that's the problem, Hartmuts code compiles with a plain function that takes the same amount and types of arguments as Beep.
example:
bool foo(DWORD a, DWORD b)
{
}
px::bind(&foo,123,456); //compiles
px::bind(&Beep,123,456); // doesn't compile and generates the error message above.
A google search revealed to me that (most) WINAPI functions use the __stdcall convention, which is not the default convention, __cdecl, which C/C++ functions with the compiler option /Gd use, like in this case: foo
So the answers given so far were all correct, the phoenix solution just didn't work out of the box for me.
(Which motivated me to post this question in the first place. I'm sorry for it's undignified and confusing nature, maybe this clears it all up now.)
The only thing unclear to me now is...how I would make phoenix get along with __stdcall, but that should probably be a separate question.
As John said you could use boost::bind. You have to be very careful not to mix and match placeholder variables from different libraries, though. When using boost::bind you need to use its placeholder variables, i.e. ::_1 (yes, boost::bind's placeholders are in global namespace - yuck).
The best solution (and the safest in terms of compatibility) is to utilize boost::phoenix::bind. This is compatible with boost::bind and anything you can do there is possible with phoenix::bind as well (and more). Moreover, Spirit 'understands' Phoenix constructs and exposes all of it's internals using special placeholder variables which are implemented using Phoenix themselves.
In your case the code would look like:
namespace phx = boost::phoenix;
some_parser[phx::bind(&Beep, 123, 456)];
which will call Beep(123, 456) whenever some_parser matches.
I imagine you can use Boost Bind. Instead of writing a wrapper function and giving its address to Qi, you could do this:
boost::bind( Beep, 123, 456 );
This will build a binding which discards its own arguments and calls Beep(123, 456). If you wanted to pass its argument along as well (not that you do here, just to illustrate something common), you can do this:
boost::bind( Beep, 123, 456, _1 );
Then it will call Beep(123, 456, the_string)
All,
I am writing a small c++ app and have been stumped by this issue. Is there a way to create (and later catch ) the error while accessing element from va_list macro using va_arg if element type is not expected. Eg:-
count=va_arg(argp,int);
if (count <= 0 || count > 30)
{
reportParamError(); return;
}
Now, if I am passing a typedef instead of int, I get garbage value on MS compiler but 95% of time count gets value 0 on gcc (on 64 bit sles10 sys). Is there a way I can enforce some typechecking, so that I get an error that can be caught in a catch block?
Any ideas on this would be very helpful to me. Or is there a better way to do this. The function prototype is:-
void process(App_Context * pActx, ...)
The function is called as
process(pAtctx,3,type1,type2,type3);
It is essential for pActx to be passed as 1st parameter and hence cannot pass count as 1st parameter.
Update-1
Ok, this sounds strange but nargs does not seem to part of va_list on sles10 gcc. I had to put in
#ifdef _WIN32
tempCount=va_arg(argp,int)
#endif
After using this, parameters following nargs do not get garbage values. However, this introduces compiler/platform based #ifdefs....Thanks Chris and Kristopher
If you know a count will always be passed as the second argument, then you could always change the signature to this:
void process(App_Context * pActx, int count, ...)
If that's not an option, then there is really no way to catch it. That's just how the variable-argument-list stuff works: there is no way for the callee to know what arguments are being passed, other than whatever information the caller passes.
If you look into how the va_arg macro and related macros are implemented, you may be able to figure out how to inspect all the stuff on the stack. However, this would not be portable, and it is not recommended except as a debugging aid.
You also might want to look into alternatives to variable-arguments, like function overloading, templates, or passing a vector or list of arguments.
No, there is no way. varargs doesn't provide any way to check the types of parameters passed in. You must only read them with the correct type which means that you need another way of communicating type information.
You are likely to be better off avoiding varargs functionality unless you really need it. It's only really a C++ feature for the sake of legacy functions such as printf and friends.
Is something like this allowed in C++? If so, how do I do it?
myFunction("User input: %s", a);
Or is the only way to format it first and then pass it?
If you want to write a function that takes variable parameters, the answer is yes, and here's how you declare such a function:
void myFunction(const char*, ...);
Note the elipsis at the end.
But now that you know how to do this, I'll complicate things for you. You should not do this. The myFunction() declared above is type-unsafe, and completely sidesteps every means C++ has to protect you from mistakes.
There are other ways to accomplish something like this (vector comes to mind), but I have found that if you're needing a function that takes variable parameters, it's a code smell that indicates that there is somethign wrong with your design in the first place. Take a closer look at why you need this.
EDIT:
If what you're trying to do is not pass variable parameters per se, but a formatted string (like your OP says), then you would need to do the string formatting yourself in your function. There are ways to do this depending on your platform. In Windows, you'd probably use vsprintf() or something similar.
But again, if you need to do this, there are better ways. Personally I'm fond of using Boost format.
I guess what you want is to call a function like vsprintf from your myFunction - this way you can do the formatting inside of your function. Example:
void myFunction(const char *format, ...)
{
char buf[1024];
va_list arglist;
va_start( arglist, format );
vsprintf(buf,format,arglist);
va_end( arglist );
}
It's legal to do what you're doing, except:
sprintf's behavior is to apply formatting to a string. Outside of that function (and the printf family in general), your arguments here don't really 'mean' anything, because your function signature could look like this:
void myFunction(const char* str1, const char* str2);
But what it does is up to you.
If you want a string modified before passing it into some function, you will either have to modify it outside myFunction (via sprintf or whatever) or pass all your arguments in and call sprintf inside the function.
Yes, it's allowed. No, it is not a part of the standard library, so you have to implement it yourself.
It is possible using the vsprintf() function from the C library, and writing myFunction() as taking variable arguments.
However, the usual disclaimers regarding variable argument methods apply: it's very easy to introduce buffer overruns or segmentation violations this way. Some compilers allow you to declare myFunction() as "printf-like", so that you could get some degree of compile-time checking of the arguments, but that is not portable.
I came across the following weird chunk of code.Imagine you have the following typedef:
typedef int (*MyFunctionPointer)(int param_1, int param_2);
And then , in a function , we are trying to run a function from a DLL in the following way:
LPCWSTR DllFileName; //Path to the dll stored here
LPCSTR _FunctionName; // (mangled) name of the function I want to test
MyFunctionPointer functionPointer;
HINSTANCE hInstLibrary = LoadLibrary( DllFileName );
FARPROC functionAddress = GetProcAddress( hInstLibrary, _FunctionName );
functionPointer = (MyFunctionPointer) functionAddress;
//The values are arbitrary
int a = 5;
int b = 10;
int result = 0;
result = functionPointer( a, b ); //Possible error?
The problem is, that there isn't any way of knowing if the functon whose address we got with LoadLibrary takes two integer arguments.The dll name is provided by the user at runtime, then the names of the exported functions are listed and the user selects the one to test ( again, at runtime :S:S ).
So, by doing the function call in the last line, aren't we opening the door to possible stack corruption? I know that this compiles, but what sort of run-time error is going to occur in the case that we are passing wrong arguments to the function we are pointing to?
There are three errors I can think of if the expected and used number or type of parameters and calling convention differ:
if the calling convention is different, wrong parameter values will be read
if the function actually expects more parameters than given, random values will be used as parameters (I'll let you imagine the consequences if pointers are involved)
in any case, the return address will be complete garbage, so random code with random data will be run as soon as the function returns.
In two words: Undefined behavior
I'm afraid there is no way to know - the programmer is required to know the prototype beforehand when getting the function pointer and using it.
If you don't know the prototype beforehand then I guess you need to implement some sort of protocol with the DLL where you can enumerate any function names and their parameters by calling known functions in the DLL. Of course, the DLL needs to be written to comply with this protocol.
If it's a __stdcall function and they've left the name mangling intact (both big ifs, but certainly possible nonetheless) the name will have #nn at the end, where nn is a number. That number is the number of bytes the function expects as arguments, and will clear off the stack before it returns.
So, if it's a major concern, you can look at the raw name of the function and check that the amount of data you're putting onto the stack matches the amount of data it's going to clear off the stack.
Note that this is still only a protection against Murphy, not Machiavelli. When you're creating a DLL, you can use an export file to change the names of functions. This is frequently used to strip off the name mangling -- but I'm pretty sure it would also let you rename a function from xxx#12 to xxx#16 (or whatever) to mislead the reader about the parameters it expects.
Edit: (primarily in reply to msalters's comment): it's true that you can't apply __stdcall to something like a member function, but you can certainly use it on things like global functions, whether they're written in C or C++.
For things like member functions, the exported name of the function will be mangled. In that case, you can use UndecorateSymbolName to get its full signature. Using that is somewhat nontrivial, but not outrageously complex either.
I do not think so, it is a good question, the only provision is that you MUST know what the parameters are for the function pointer to work, if you don't and blindly stuff the parameters and call it, it will crash or jump off into the woods never to be seen again... It is up to the programmer to convey the message on what the function expects and the type of parameters, luckily you could disassemble it and find out from looking at the stack pointer and expected address by way of the 'stack pointer' (sp) to find out the type of parameters.
Using PE Explorer for instance, you can find out what functions are used and examine the disassembly dump...
Hope this helps,
Best regards,
Tom.
It will either crash in the DLL code (since it got passed corrupt data), or: I think Visual C++ adds code in debug builds to detect this type of problem. It will say something like: "The value of ESP was not saved across a function call", and will point to code near the call. It helps but isn't totally robust - I don't think it'll stop you passing in the wrong but same-sized argument (eg. int instead of a char* parameter on x86). As other answers say, you just have to know, really.
There is no general answer. The Standard mandates that certain exceptions be thrown in certain circumstances, but aside from that describes how a conforming program will be executed, and sometimes says that certain violations must result in a diagnostic. (There may be something more specific here or there, but I certainly don't remember one.)
What the code is doing there isn't according to the Standard, and since there is a cast the compiler is entitled to go ahead and do whatever stupid thing the programmer wants without complaint. This would therefore be an implementation issue.
You could check your implementation documentation, but it's probably not there either. You could experiment, or study how function calls are done on your implementation.
Unfortunately, the answer is very likely to be that it'll screw something up without being immediately obvious.
Generally if you are calling LoadLibrary and GetProcByAddrees you have documentation that tells you the prototype. Even more commonly like with all of the windows.dll you are provided a header file. While this will cause an error if wrong its usually very easy to observe and not the kind of error that will sneak into production.
Most C/C++ compilers have the caller set up the stack before the call, and readjust the stack pointer afterwards. If the called function does not use pointer or reference arguments, there will be no memory corruption, although the results will be worthless. And as rerun says, pointer/reference mistakes almost always show up with a modicum of testing.