C++ function parameters or parameter array - c++

My background and instincts tell me I should always create a tighter and more explicit interface to a function by requiring parameters like this:
bool someFunc(int param1, int param2, char param3, float param4) {
...
}
or requiring an object (struct or class) like:
class someObject {
...
int p1;
int p2;
char c1;
float p4;
}
I have been told by my boss that I should be using something like:
bool someFunc(void *params[], int size) {
...
}
because it creates more extensible (you can iterate over parameters this way) and faster code.
I am only interested in improving my abilities, but my instincts go against this method. Is he right?

Horrible idea. I can't list the reasons why it's bad in a single answer, but the main problem is that it just doesn't work. As a simple example, you can't pass 3, and if you pass 0 it becomes a nullptr. More importantly, you have to cast the values back to a given type anyway, so why not specify the type in the signature?
Now there's a real C++ alternative, variadic templates:
template<typename... Arguments>
void Foo(Arguments... parameters);
In this case, the compiler will know all the types in Arguments..., there's no need to cast anything.

I disagree with the above answer, your instincts are right you should try and create a explicit interface to a function. There are times where you can't have an explicit interface, and then you should consider variadic template arguments, but they're rare. Two Ints a char and float seem like a perfectly reasonable function parameters.
However you're in a very sticky situation, you don't want to go against your boss. I would be skeptical of any programming advice from him, he's either not a very good programmer or worse one of those old school hacky c programmers (see if he uses MACROS everywhere). My advice is to do it his way now, then if you're ever working with that function again later fix it and try and get someone else to review your code.

Your boss is crazy. Such debauchery had some place in C, and even there you would use varargs, not this crazy construct. If you want to program in a dynamically-typed language, either don't use C++, or use arrays of variant types (say boost::variant or QVariant).
The "extensibility" your boss is looking for and obviously missing is otherwise known as function/method overloading. It has its place as a part of a proper design, not as an edict.

Related

reducing countless template keywords in C++?

I have a pretty simple code as the following.
template<typename T>
struct cell{
int nr;
T* someInfo;
};
template<typename T>
void doSomething(cell<T> c)
{
cout<<c.nr;
}
I actually have numerous functions using cells, very few using the T* template info (above code does not use it). Can I write my program (in C++98) without ending up with
countless template keywords, T* or cell stuff? I want to reduce clutter, to write a
rather C-like C++ code, easy to read by those who are not familiar with
C++. Can I make the compiler understand (without macros) that whenever it sees cell, it
is actually cell<T> and it has to put a template on the function?
If there is no C++98 solution, I prefer a C way using void* instead of T*. That comes with no clutter in the rest of the code, but I can't delete c.someInfo, but only
free(c.someInfo).
Reuse code by inheritance from a non-templated base class.
struct cell_base {
int nr;
};
template<typename T>
struct cell : cell_base {
T* someInfo;
};
void doSomething(cell_base const& c)
{
cout<<c.nr;
}
So whatever needs the non-templated bits accepts a cell_base, and the few things that do need the template parameter can be templates.
If you want to use templates, then you need to use the correct template syntax.
Which does indeed mean writing T quite a few times as well as template<typename T>. That's life: the compiler does some very clever things, and needs this "boilerplate" in order to disambiguate.
You can reduce the amount of typing by writing all the functions inline inside the class declaration.
Using (void*) instead would be anachronistic.
You can typedef your template; and which will completely hide the fact that it's a template for a specific type. ie
typedef cell<int> IntCell;
then usage of the type
void doSomething(const IntCell& c) {}
Edit: I now realize that you asked about c++98. My suggestion requires c++14 unfortunately.
You could use generic lambdas in place of template functions:
auto doSomething = [](auto c) {
cout<<c.nr;
}
If you're willing to wait for a bit, there is the concepts proposal for the C++ standard which will hopefully be included in C++20. It includes generic functions which could allow:
void doSomething(auto c)
{
cout<<c.nr;
}
Or
void doSomething(Concept c)
{
cout<<c.nr;
}
Where Concept is a concept that all cell<T> satisfy. This is a compile time analogue to the runtime inheritance suggested by StoryTeller.
Hoping this can be useful for somebody someday, I'll explain why I ended up with the
old-school C solution in C++. You maybe need to be in the same mess as me to understand,
i.e., you need to deal with some minor unknown pointer for which you do not want to clutter
a C++ code which already has many classes that can not be ported to C in reasonable time.
I thank all the responses I received, and after considering them, I regret they could not solve
my problems. Even with inheritance, I still end up with hundreds of template and <T>
stuff because I have many classes and sub-classes with cell members.
It is easier/cleaner to use void* someInfo as in C, as that does not require modifying all
classes that contain cells. The problem of deleting the void* pointer is left to the user
of the library. It's easy to allow/ask the user to make a unique call like
set_func_free_info(&custom_free_func). The deallocation function of the library could be:
if(func_free_info!=NULL)
func_free_info(c.someInfo);
else //don't let it get here if someInfo points to an object
free(c.someInfo); //needing a destructor, do use set_func_free_info(...).
Given some of the responses, I feel you :
might argue void* is "anachronistic". Maybe. If somebody told me that such an old language
like English is anachronistic faced to modern Esperanto, I would feel the same.
might say it is a bad idea to write code somehow for pure C programmers not familiar
with C++, in the line with a above remark ``the code ends up more complex than it needs to be
so even those who ARE familiar with C++ end up getting confused.''. If you honestly
think about this, here the opposite is true : the code is less complex by avoiding C++
features, as the template constructs would clutter all the code for a minor feature.
ask why don't stick to pure C and simply finish the story. I can't, because this is
part of a code where someInfo can be an object. So I end up
with the C-like C++ style that some here seem to hate, but you can really find reasons for it on
the linked material my comment above.
Anyway, M Stroustrup said that
C++ is deliberately designed to support a variety of
styles rather than a would-be "one true way".
So if you like to lecture about "your
true C++ way", you should understand you shouldn't do it. And you'll see life so much
more than a foolish game. C++ supports infinitely many more styles and possibilities than
C, e.g., I could use lambdas as in one of the replies, but too many would not understand it.

Is there a legitimate use for void*?

Is there a legitimate use of void* in C++? Or was this introduced because C had it?
Just to recap my thoughts:
Input: If we want to allow multiple input types we can overload functions and methods, alternatively we can define a common base class, or template (thanks for mentioning this in the answers). In both cases the code get's more descriptive and less error prone (provided the base class is implemented in a sane way).
Output: I can't think of any situation where I would prefer to receive void* as opposed to something derived from a known base class.
Just to make it clear what I mean: I'm not specifically asking if there is a use-case for void*, but if there is a case where void* is the best or only available choice. Which has been perfectly answered by several people below.
void* is at least necessary as the result of ::operator new (also every operator new...) and of malloc and as the argument of the placement new operator.
void* can be thought as the common supertype of every pointer type. So it is not exactly meaning pointer to void, but pointer to anything.
BTW, if you wanted to keep some data for several unrelated global variables, you might use some std::map<void*,int> score; then, after having declared global int x; and double y; and std::string s; do score[&x]=1; and score[&y]=2; and score[&z]=3;
memset wants a void* address (the most generic ones)
Also, POSIX systems have dlsym and its return type evidently should be void*
There are multiple reasons to use void*, the 3 most common being:
interacting with a C library using void* in its interface
type-erasure
denoting un-typed memory
In reverse order, denoting un-typed memory with void* (3) instead of char* (or variants) helps preventing accidental pointer arithmetic; there are very few operations available on void* so it usually require casting before being useful. And of course, much like with char* there is no issue with aliasing.
Type-erasure (2) is still used in C++, in conjunction with templates or not:
non-generic code helps reducing binary bloat, it's useful in cold paths even in generic code
non-generic code is necessary for storage sometimes, even in generic container such as std::function
And obviously, when the interface you deal with uses void* (1), you have little choice.
Oh yes. Even in C++ sometimes we go with void * rather than template<class T*> because sometimes the extra code from the template expansion weighs too much.
Commonly I would use it as the actual implementation of the type, and the template type would inherit from it and wrap the casts.
Also, custom slab allocators (operator new implementations) must use void *. This is one of the reasons why g++ added an extension of permitting pointer arithmatic on void * as though it were of size 1.
Input: If we want to allow multiple input types we can overload
functions and methods
True.
alternatively we can define a common base
class.
This is partially true: what if you can't define a common base class, an interface or similar? To define those you need to have access to the source code, which is often not possible.
You didn't mention templates. However, templates cannot help you with polymorphism: they work with static types i.e. known at compile time.
void* may be consider as the lowest common denominator. In C++, you typically don't need it because (i) you can't inherently do much with it and (ii) there are almost always better solutions.
Even further, you will typically end up on converting it to other concrete types. That's why char * is usually better, although it may indicate that you're expecting a C-style string, rather than a pure block of data. That's whyvoid* is better than char* for that, because it allows implicit cast from other pointer types.
You're supposed to receive some data, work with it and produce an output; to achieve that, you need to know the data you're working with, otherwise you have a different problem which is not the one you were originally solving. Many languages don't have void* and have no problem with that, for instance.
Another legitimate use
When printing pointer addresses with functions like printf the pointer shall have void* type and, therefore, you may need a cast to void*
Yes, it is as useful as any other thing in the language.
As an example, you can use it to erase the type of a class that you are able to statically cast to the right type when needed, in order to have a minimal and flexible interface.
In that response there is an example of use that should give you an idea.
I copy and paste it below for the sake of clarity:
class Dispatcher {
Dispatcher() { }
template<class C, void(C::*M)() = C::receive>
static void invoke(void *instance) {
(static_cast<C*>(instance)->*M)();
}
public:
template<class C, void(C::*M)() = &C::receive>
static Dispatcher create(C *instance) {
Dispatcher d;
d.fn = &invoke<C, M>;
d.instance = instance;
return d;
}
void operator()() {
(fn)(instance);
}
private:
using Fn = void(*)(void *);
Fn fn;
void *instance;
};
Obviously, this is only one of the bunch of uses of void*.
Interfacing with an external library function which returns a pointer. Here is one for an Ada application.
extern "C" { void* ada_function();}
void* m_status_ptr = ada_function();
This returns a pointer to whatever it was Ada wanted to tell you about. You don't have to do anything fancy with it, you can give it back to Ada to do the next thing.
In fact disentangling an Ada pointer in C++ is non-trivial.
In short, C++ as a strict language (not taking into account C relics like malloc()) requires void* since it has no common parent of all possible types. Unlike ObjC, for example, which has object.
The first thing that occurs to my mind (which I suspect is a concrete case of a couple of the answers above) is the capability to pass an object instance to a threadproc in Windows.
I've got a couple of C++ classes which need to do this, they have worker thread implementations and the LPVOID parameter in the CreateThread() API gets an address of a static method implementation in the class so the worker thread can do the work with a specific instance of the class. Simple static cast back in the threadproc yields the instance to work with, allowing each instantiated object to have a worker thread from a single static method implementation.
In case of multiple inheritance, if you need to get a pointer to the first byte of a memory chunk occupied by an object, you may dynamic_cast to void*.

C++ using struct arguments for functions instead of multiple arguments?

Anybody think there are advantages to using a class or struct to pass arguments ?
Like instead of
f(int,float,string)
Have
f(Args)
Where Args is struct with int,float,string members.
Advantage is easy to create multiple default parameters and not have to change function signature when new arguments added.
The obvious benefit would be to have logical grouping of semantically related data items.
Once you do, add some (member) operations on the structure that will guarantee your invariants.
The encapsulation raises the abstraction level of your code and this makes it easier to maintain/reason about.
See also Law Of Demeter
I think the great advantage is not having to rely to parameter order. Rely on order is error prone if you are changing frequently the interface, instead if you change the parameter struct you are always explicitly assigning values to a member variable which has a specific semantic.
Take for example Direct3D11 ID3D11Device::CreateDepthStencilState function: passing a const D3D11_DEPTH_STENCIL_DESC *pDepthStencilDescis a lot more clear than asking for all the parameter it require.
Moreover think about modifiability: you don't need to change this method signature but only the underlying data structure during refactoring. I've found this especially useful when working collaboratively, where someone specify the interface and someone else have to implement it.
Anybody think there are advantages to using a class or struct to pass arguments ?
Yes, I think there's a lot of advantages.
Having large parameter lists on functions will distract client code from semantical parameter consistency, which can be better managed within an appropriate struct or class.
Also it's more flexible to use a struct, if additional (possibly optional) parameters need to be added later.
Whether you use one argument contained in a class/struct or multiple arguments depends on the meanings of the arguments.
Bad use of a struct:
struct Foo
{
char const* source;
char* destination;
};
Foo strcpy(Foo foo);
Good use of a struct:
struct Point
{
int x;
int y;
};
int distanceFromOrigin(Point p) { ... }
instead of
int distanceFromOrigin(int x, int y) { ... }
Doing the devil advocate here. There are also drawbacks here, mostly semantical. The first and foremost, it will require a lot of code if some of those args are passed by reference, another one by constant reference, the third one by const pointer and the forth by value. Would require you to explicitly write move constructor and default constructor for the argument struct, which will quickly become tedious. It would also be tedious to add members to that struct.
I also think using a struct is better: You can circumvent the hustle with parameter types and order. Suppose you have foo(A, B) (for types A and B). But still foo(b, a) might compile, depending on implicit constructions etc.
This concept can also be generalized using some kind of Context classes. Relying on C++11 variadic templates you could pass a "parameter superset context" to a subset one.

Why would there be such a requirement for different arguments of the same template parameter?

In page 671 of his new book Mr Stroustrup wrote the following sentence:
Note that there is no requirement that different arguments for the
same template parameter should be related by inheritance.
I can understand what the author wrote, but I can't understand the reason why he inserted this comment in the text. I think I'm missing something here, but I don't know exactly what.
When introducing the concept of templates, he tries to make clear that its not some kind of polymoprhism.
Before template were invented and added to C++ you could write generic code only using inheritance (or multilple inheritance).
Another concept that Mr.Stroustrup certainly want the reader not to confuse with templates is interfaces. In the java comunity for example this is a very popular technique and many books abot OOP explain this concept. Interfaces allow you to use some kind of generic code with a class, at the condition that the class is defined to implement (not inherit) a specific interface. All classes using the interface must be related to it. It's not strictly speaking inheritance, but it's a kind of substitute to multiple inheritance.
Templates can be used with any object or class without its type being related in advance to anything in common.
The answer is simple if we look at the use case of templates from the perspective of someone who is totally new to the concept of templates.
int i;
double d;
char c;
print(&i); //prints an integer
print(&d); //prints a double
print(&c); //prints a char
From the perspective of someone who does not understand C++ templates, he/she would assume that the prototype of print looks something like this.
print(SomeBaseType* pdata);
OR
print(void* pdata);
However, what happens with templates is with a function template such as
template <typename T>
print(T* pdata);
for the above use case, the compiler generates three functions during compile-time
print(int* pdata);
print(double* pdata);
print(char* pdata);
and through function overload resolution, the right function gets called.
Thank you for reading.
Disclaimer: A print function might not be the best example.

reuse function logic in a const expression

I think my question is, is there anyway to emulate the behaviour that we'll gain from C++0x's constexpr keyword with the current C++ standard (that is if I understand what constexpr is supposed to do correctly).
To be more clear, there are times when it is useful to calculate a value at compile time but it is also useful to be able to calculate it at runtime too, for e.g. if we want to calculate powers, we could use the code below.
template<int X, unsigned int Y>
struct xPowerY_const {
static const int value = X*xPowerY_const<X,Y-1>::value;
};
template<int X>
struct xPowerY_const<X, 1> {
static const int value = X;
};
int xPowerY(int x, unsigned int y) {
return (y==1) ? x : x*xPowerY(x,y-1);
}
This is a simple example but in more complicated cases being able to reuse the code would be helpful. Even if, for runtime performance, the recursive nature of the function is suboptimal and a better algorithm could be devised it would be useful for testing the logic if the templated version could be expressed in a function, as I can't see a reasonable method of testing the validity of the constant template method in a wide range of cases (although perhaps there is one and i just can't see it, and perhaps that's another question).
Thanks.
Edit
Forgot to mention, I don't want to #define
Edit2 Also my code above is wrong, it doesn't deal with x^0, but that doesn't affect the question.
Template metaprogramming implements logic in an entirely different (and incompatible) way from "normal" C++ code. You're not defining a function, you're defining a type. It just happens that the type has a value associated with it, which is built up from a combination of other types.
Because the templates define types, there is no program logic involved. The logic is simply a side effect of the compiler trying to resolve relationships between the templated types. There really isn't any way to automatically extract the high level logic from a template "program" into a function.
FWIW, template metaprogramming wasn't even a glimmer in Bjarne's eye when templates were first implemented. They were actually discovered later on in the language's life by users of the language. It's an "unintended" side-effect of the type system that just happened to become very popular. It's precisely because of this discovery that new features are being added to the language to more thoroughly support the idioms that have evolved.