Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ function argument safety

Tags:

c++

c++14

In a function that takes several arguments of the same type, how can we guarantee that the caller doesn't mess up the ordering?

For example

void allocate_things(int num_buffers, int pages_per_buffer, int default_value ... 

and later

// uhmm.. lets see which was which uhh.. allocate_things(40,22,80,... 
like image 838
Anonymous Entity Avatar asked Aug 08 '16 19:08

Anonymous Entity


People also ask

What is the argument of a function in C?

The values that are declared within a function when the function is called are known as an argument. The variables that are defined when the function is declared are known as parameters. 2. These are used in function call statements to send value from the calling function to the receiving function.

How many arguments should a function have C?

Neither the C nor C++ standard places an absolute requirement on the number of arguments/parameters you must be able to pass when calling a function, but the C standard suggests that an implementation should support at least 127 parameters/arguments (§5.2.

Are C function arguments pass by value?

In C All arguments to functions are passed by value In pass by reference (also called pass by address), a copy of the address of the actual parameter is stored. Use pass by reference when you are changing the parameter passed in by the client program.

What are the three types of function arguments?

5 Types of Arguments in Python Function Definition:keyword arguments. positional arguments. arbitrary positional arguments.


2 Answers

A typical solution is to put the parameters in a structure, with named fields.

AllocateParams p; p.num_buffers = 1; p.pages_per_buffer = 10; p.default_value = 93; allocate_things(p); 

You don't have to use fields, of course. You can use member functions or whatever you like.

like image 104
Dietrich Epp Avatar answered Sep 19 '22 23:09

Dietrich Epp


If you have a C++11 compiler, you could use user-defined literals in combination with user-defined types. Here is a naive approach:

struct num_buffers_t {     constexpr num_buffers_t(int n) : n(n) {}  // constexpr constructor requires C++14     int n; };  struct pages_per_buffer_t {     constexpr pages_per_buffer_t(int n) : n(n) {}     int n; };  constexpr num_buffers_t operator"" _buffers(unsigned long long int n) {     return num_buffers_t(n); }  constexpr pages_per_buffer_t operator"" _pages_per_buffer(unsigned long long int n) {     return pages_per_buffer_t(n); }  void allocate_things(num_buffers_t num_buffers, pages_per_buffer_t pages_per_buffer) {     // do stuff... }  template <typename S, typename T> void allocate_things(S, T) = delete; // forbid calling with other types, eg. integer literals  int main() {     // now we see which is which ...     allocate_things(40_buffers, 22_pages_per_buffer);      // the following does not compile (see the 'deleted' function):     // allocate_things(40, 22);     // allocate_things(40, 22_pages_per_buffer);     // allocate_things(22_pages_per_buffer, 40_buffers); } 
like image 29
sergej Avatar answered Sep 23 '22 23:09

sergej