I have defined a vararg for list as below in method definition ,
List<String>... valuesList
For example,the below method is to create a sql query with 'where clause' conditions as an input by user.
getRecords(List<String> dbColumnList,List<String>... valuesList)
Is it a good practice to define an API method like this ? The reason I am asking because the compiler throws a warning , "Type safety: A generic array of List is created for a varargs parameter".
Please provide your comments and suggestions.
Krithika,
firstly the issue depends from the version used and will change again in future version.
IMHO it is NOT an issue about "good practice", it is a "vulnerability" of varargs. Since, varargs (as you know) is an array and Java does not permit the creation of arrays of parameterized types, the compiler converts the varargs formal parameter to Object[] ( List[] instead of List[] in the given case) elements losing the "real type".
Then, having taken note of this issue, use varargs only for primitive type when you finish the write API. However, Java knows this issue: see also the dedicated annotation on java 7 #SafeVarargs
http://docs.oracle.com/javase/7/docs/api/java/lang/SafeVarargs.html
if java "admits it", this way should be acceptable.
Finally, see the official documentation.
Related
It's easy to do something like that in Python, but implementing it in C++ seems to be more challenging.
I actually have some solution to this, but I'd like to see if you can see any better solution.
Here's what I want to do.
I have a list of values of different types (string, integer, can be also instance of some class etc.). Now here's the first problem - in C++ (unlike in Python) all values in vector/array have to be of the same type.
The solution I can see is that I can use std::any like this: vector<std::any> list.
I also have an array/vector of functions (or pointers to functions) with different parameter types and returned values - one function can accept string and integer and return a char and other can accept a char and return an int. Here's another problem: in C++ you can have an array/vector of functions only if they have the same parameters and returned values (as far as I know) because in your declaration of the vector you need to define the parameter types and the returned value.
The other problem is that I need to retrieve the information about the parameters and the returned value for each function. In other words, having those functions, I need to know that this function accepts 2 strings and 1 integer and returns a char for example. In Python I can use inspect.signature function to retrieve information about type annotations of a function. In C++, I don't know if there is a way to do this.
The solution I can see here is to use std::any again (although I will use another solution, I will explain why later).
The solution I can see to this problem is that I won't retrieve that information but instead the user of the class which accepts this vector of functions will simply have to specify what are the parameter types and returned value for each function. In other words, the solution I can see is that I won't be retrieving the information about parameter types programmatically.
The other problem I have is that later I need to call one of those functions with some parameters. In Python I do this like this:
arguments = [1, 'str', some_object] // here I prepare a list of arguments (they are of different types)
func(**arguments)
In C++ I can do unpacking as well, but not if the parameters are of different types.
The solution I can see here is as follows. Those functions in the vector will all accepts only argument which is vector<std::any> args which will simply contain all of the arguments. Later when I want to call the function, I will simply construct a vector with std::any values and pass it as an argument. This would also solve the previous problem of not being able to store vector of functions with different parameters.
Can you see better solutions?
You might wonder what I need all of this is for. I do some program synthesis stuff and I need to programmatically construct programs from existing functions. I'm writing a library and I want the user of my library to be able to specify those base functions out of which I construct programs. In order to do what I want, I need to know what are the parameters and returned values of those functions and I need to call them later.
I believe what you are looking for is std::apply. You can use std::tuple instead of std::vector to store a list of values of different types -- as long as the types are known at compile-time. Then std::apply(f, t) in C++ is basically the same as f(*t) in Python.
I have a list of values of different types (string, integer, can be also instance of some class etc.).
A type which is a union of subtypes is called a sum type or tagged union. C++ has the template std::variant for that.
Now here's the first problem - in C++ (unlike in Python) all values in vector/array have to be of the same type.
Of course, so use cleverly C++ containers. You might want some std::map or std::vector of your particular instance of std::variant.
I also have an array/vector of functions
You probably want some std::vector of std::function-s and code with C++ lambda expressions
You should read a good C++ programming book
I'm writing a library and I want the user of my library to be able to specify those base functions out of which I construct programs.
You could get inspiration from SWIG and consider generating some C++ code in your library. So write (in Python or C++) your C++ metaprogram (generating some C++ code, like ANTLR does) which generates the user code, and your user would adapt his build automation tool for such a need (like users of GNU bison do).
You might also consider embedding Guile (or Lua) in your application.
PS. You might be interested by other programming languages like Ocaml, Go, Scheme (with Guile, and read SICP), Common Lisp (with SBCL), or Rust.
Usually in my code I need to use specific functions for various variables i.e.
object->SetStatus("var1",1); object->SetAddress("var1",&var1);
object->SetStatus("var2",1); object->SetAddress("var2",&var2);
object->SetStatus("var3",1); object->SetAddress("var3",&var3);
...
My idea is to use a function that will do this automatically by calling it, i.e.
object->function(var1,var2,var3,...);
To achieve that I have to solve 3 issues
I need to read the number of arguments when calling function()
I need to parse somehow the argument names inside the code
Since the variables are not of the same type, I need to find a way to make function() type "transparent"
Since I am newbie in c++ coding, I tried to search fo something similar, but I couldn't find anything.
Any help, advice or remark is more than welcome!
There are multiple ways to do so. One way is make a Base class and all your variable type will inherit from this base class. Then pass a map<string,Base> as an argument to you function. name of variable will be key and value will be actual variables. Iterate through the map and set and assign values to methods.
You could consider some variadic template, if coding in C++11 or C++14. There is considerable literature about that subject (e.g. this tutorial), which is a bit tricky (so explaining it here is not reasonable). Read also about parameter pack
You could also use C style varargs using <cstdarg>
Perhaps std::initializer_list could be useful too.
Is it possible to pass a function a parameter of an unknown type in D. I would like to pass a parameter that could be either a struct, char[], string or int. Is this possible? I am new to D so please forgive my ignorance. Thank you
I bet you are looking for templates.
D has a great language reference that is free online.
Another option, besides templates is the std.variant module. Its functionality can be very useful in some situations like interfacing dynamic languages. For example some of the packages on http://code.dlang.org dealing with data languages (like YAML, JSON and SDL) use Algebraic for representing nodes (or values) inside documents.
I'm experimenting with variable arguments in C++, using va_args. The idea is useful, and is indeed something I've used a lot in C# via the params functionality. One thing that frustrates me is the following excerpt regarding va_args, above:
Notice also that va_arg does not determine either whether the retrieved argument is the last argument passed to the function (or even if it is an element past the end of that list).
I find it hard to believe that there is no way to programmatically determine the number of variable arguments passed to the function from within that function itself. I would like to perform something like the following:
void fcn(int arg1 ...)
{
va_list argList;
va_start(argList, arg1);
int numRemainingParams = //function that returns number of remaining parameters
for (int i=0; i<numRemainingParams; ++i)
{
//do stuff with params
}
va_end(argList);
}
To reiterate, the documentation above suggests that va_arg doesn't determine whether the retrieved arg is the last in the list. But I feel this information must be accessible in some manner.
Is there a standard way of achieving this?
I find it hard to believe that there is no way to programmatically determine the number of variable arguments passed to the function from within that function itself.
Nonetheless, it is true. C/C++ do not put markers on the end of the argument list, so the called function really does not know how many arguments it is receiving. If you need to mark the end of the arguments, you must do so yourself by putting some kind of marker at the end of the list.
The called function also has no idea of the types or sizes of the arguments provided. That's why printf and friends force you to specify the precise datatype of the value to interpolate into the format string, and also why you can crash a program by calling printf with a bad format string.
Note that parameter passing is specified by the ABI for a particular platform, not by the C++/C standards. However, the ABI must allow the C++/C standards to be implementable. For example, an ABI might want to pass parameters in registers for efficiency, but it might not be possible to implement va_args easily in that case. So it's possible that arguments are also shadowed on the stack. In almost no case is the stack marked to show the end of the argument list, though, since the C++/C standards don't require this information to be made available, and it would therefore be unnecessary overhead.
The way variable arguments work in C and C++ is relatively simple: the arguments are just pushed on the stack and it is the callee's responsibility to somewhat figure out what arguments there are. There is nothing in the standard which provides a way to determine the number of arguments. As a result, the number of arguments are determined by some context information, e.g., the number of elements referenced in a format string.
Individual compilers may know how many elements there are but there is no standard interface to obtain this value.
What you could do instead, however, is to use variadic templates: you can determine very detailed information on the arguments being passed to the function. The interface looks different and it may be necessary to channel the arguments into some sort of data structure but on the upside it would also work with types you cannot pass using variable arguments.
No, there isn't. That's why variable arguments are not safe. They're a part of C, which lacks the expressiveness to achieve type safety for "convenient" variadic functions. You have to live with the fact that C contains constructions whose very correctness depends on values and not just on types. That's why it is an "unsafe language".
Don't use variable arguments in C++. It is a much stronger language that allows you to write equally convenient code that is safe.
No, there's no such way. If you have such a need, it's probably best to pack those function parameters in a std::vector or a similar collection which can be iterated.
The variable argument list is a very old concept inherited from the C history of C++. It dates back to the time where C programmers usually had the generated assembler code in mind.
At that time the compiler did not check at all if the data you passed to a function when calling it matched the data types the function expected to receive. It was the programmer's responsibility to do that right. If, for example, the caller called the function with a char and the function expected an int the program crashed, although the compiler didn't complain.
Today's type checking prevents these errors, but with a variable argument list you go back to those old concepts including all risks. So, don't use it if you can avoid it somehow.
The fact that this concept is several decades old is probably the reason that it feels wrong compared to modern concepts of safe code.
Is there a way to determine how many parameters a Lua function takes just before calling it from C/C++ code?
I looked at lua_Debug and lua_getinfo but they don't appear to provide what I need.
It may seem a bit like I am going against the spirit of Lua but I really want to bullet proof the interface that I have between Lua and C++. When a C++ function is called from Lua code the interface verifies that Lua has supplied the correct number of arguments and the type of each argument is correct. If a problem is found with the arguments a lua_error is issued.
I'd like to have similar error checking the other way around. When C++ calls a Lua function it should at least check that the Lua function doesn't declare more parameters than are necessary.
What you're asking for isn't possible in Lua.
You can define a Lua function with a set of arguments like this:
function f(a, b, c)
body
end
However, Lua imposes no restrictions on the number of arguments you pass to this function.
This is valid:
f(1,2,3,4,5)
The extra parameters are ignored.
This is also valid:
f(1)
The remaining arguments are assigned 'nil'.
Finally, you can defined a function that takes a variable number of arguments:
function f(a, ...)
At which point you can pass any number of arguments to the function.
See section 2.5.9 of the Lua reference manual.
The best you can do here is to add checks to your Lua functions to verify you receive the arguments you expect.
You can determine the number of parameters, upvalues and whether the function accepts variable number of arguments in Lua 5.2, by using the 'u' type to fill nups, nparams, isvararg fields by get_info(). This feature is not available in Lua 5.1.
I wouldn't do this on the Lua side unless you're in full control of Lua code you're validating. It is rather common for Lua functions to ignore extra arguments simply by omitting them.
One example is when we do not want to implement some methods, and use a stub function:
function do_nothing() end
full_api = {}
function full_api:callback(a1, a2) print(a1, a2) end
lazy_impl = {}
lazy_impl.callback = do_nothing
This allows to save typing (and a bit of performance) by reusing available functions.
If you still want to do function argument validation, you have to statically analyze the code. One tool to do this is Metalua.
No, not within standard Lua. And is Aaron Saarela is saying, it is somewhat outside the spirit of Lua as I understand it. The Lua way would be to make sure that the function itself treats nil as a sensible default (or converts it to a sensible default with something like name = name or "Bruce" before its first use) or if there is no sensible default the function should either throw an error or return a failure (if not name then error"Name required" end is a common idiom for the former, and if not name then return nil, "name required" end is a common idiom for the latter). By making the Lua side responsible for its own argument checks, you get that benefit regardless of whether the function is called from Lua or C.
That said, it is possible that your modules could maintain an attribute table indexed by function that contains the info you need to know. It would require maintenance, of course. It is also possible that MetaLua could be used to add some syntax sugar to create the table directly from function declarations at compile time. Before calling the Lua function, you would use it directly to look up any available attributes and use them to validate the call.
If you are concerned about bullet-proofing, you might want to control the function environment to use some care with what (if any) globals are available to the Lua side, and use lua_pcall() rather than lua_call() so that you catch any thrown errors.
The information you ask for is not available in all cases. For example, a Lua function might actually be implemented in C as a lua_CFunction. From Lua code there is no way to distinguish a pure Lua function from a lua_CFunction. And in the case of a lua_CFunction, the number of parameters is not exposed at all, since it's entirely dependent on the way the function is implemented.
On the other hand, what you can do is provide a system for functions writers (be it in pure Lua or in C) to advertise how many parameters their functions expect. After creating the function (function f(a, b, c) end) they would simply pass it to a global function (register(f, 3)). You would then be able to retrieve that information from your C++ code, and if the function didn't advertise its parameters then fallback to what you have now. With such a system you could even advertise the type expected by the parameters.