2

I have an assignment in which we were given an incomplete class called Mystring, with the goal of implementing all the functions of the C++ string class.

Well, some of the function declarations and definitions have const char* as a parameter, but no variable name follows, and I'm not getting any compiler errors from this.

My question is: If this is a valid parameter, what does it mean? And if it's not valid, why doesn't it generate an error? Here are examples of it being used:

bool operator==(const Mystring&, const char *);

Mystring& operator=(const char * );

I'm supposed to implement these functions, but I can't wrap my head around this seemingly incomplete parameter.

Nate T
  • 21
  • 2

5 Answers5

1

Parameter names are not required. It's just a quirk of the C++ grammar. If you decline to give a parameter a name in your function definition, then you won't be able to access its value.

Related: Why do function prototypes include parameter names when they're not required?

Peter Ruderman
  • 12,241
  • 1
  • 36
  • 58
0

The line bool operator==(const Mystring&, const char *); is just a declaration. It tells the compiler that this function takes 2 parameters of type const Mystring& and const char*. Compiler does not need the exact variable name at this point.

In you .cpp file where you would be defining your function, you would have to provide the variable names as you would use them in your logic. The compiler would compile this code and generate an executable using this code.

bool operator==(const Mystring& str, const char* subStr)
{
     //Logic here which uses variable str and subStr
}
Shrikanth N
  • 652
  • 3
  • 17
0

Welcome to Stack Overflow, Nate!

The line you provided for us is actually a function declaration. This is used for declaring the signature of a function before actually defining the body:

// Function declaration
bool operator==(const MyString&, const char*);

// Function that uses operator==
int main()
{
    MyString str = new MyString();
    char* ptr = nullptr;

    if (str == ptr)
    {
        ...
    }
}

// Function definition
bool operator==(const MyString& left, const char* right)
{
    ...
}
Isaac Corbrey
  • 553
  • 3
  • 20
  • No, the prototype is just `const MyString&, const char*`. The line in question is called a function declaration. – melpomene Oct 23 '18 at 02:33
  • @melpomene I've heard the entire header referred to as a "header", a "prototype", and a "forward declaration", and assumed they were referring to the same thing. Are they not? – Isaac Corbrey Oct 23 '18 at 02:38
  • A "header" is normally something you `#include`. A prototype is the list of declarations between `(` `)`; early C didn't have prototypes (you'd write e.g. `int main(); main(argc, argv) int argc; char **argv; { ... }`; C++ never allowed this). A "forward declaration" usually refers to `struct foo;` (because the full `struct foo { ... };` thing is also called a "declaration" in the standard, so we can't just use declaration / definition to distinguish). – melpomene Oct 23 '18 at 02:52
  • @melpomene Interesting, I'll need to go re-read up on docs. – Isaac Corbrey Oct 23 '18 at 03:14
0

The syntax you have (function without a body) is a function declaration. It just says that there is a function that will be defined or linked later that has a boolean return type, and two parameters of given types, in that order; the names are irrelevant at this point. This function declaration is also a handy way of specifying inputs and outputs in a task specification for humans. This works in both C++ and C.

In C++ specifically, you can even leave out the parameter names from the function definition (function with a body). As others say, it is legal, you just can't access such parameters. It is not allowed in C.

When you implement your function according to the task, it is almost certain you will want to insert names; what they are will be up to you.

Amadan
  • 191,408
  • 23
  • 240
  • 301
0

If this is a valid [formal] parameter, what does it mean?

Yes ... the unnamed [formal] parameter is valid and useful in least two ways.

1) an invoking code can provide an [actual] parameter, even if the [formal] parameter is not named. This does not require the implementation to use it, and is a common approach to avoiding some specific warnings.

example:

int main (int, char**) {  return foo();  }
int main (int argc, char* argv[]) { return foo(argc, argv); }

Both are valid implementations. In the first, foo has no use for the parameters, and by not naming them, the compiler will not generate warnings about 'unused arguments'. Yes, the runtime always presents an argc, but it will be 0 when the shell finds no parameters. Note that in the first example, the int (for argc) will be provided (the value 0 indicates the array does not), and the invocation of foo() never references it.

2) the function parameters contribute to the 'signature' of a function.

Mystring& foo(const char * ); // 1
Mystring& foo();              // 2
Mystring& foo(const int&  );  // 3

the 3 foo(...)'s are unique. This allows the compiler to select the best match (or generate an error that the invocation does not match any version), and the linker to find the appropriate implementation of foo().

And if it's not valid, why doesn't it generate an error?

The [formal] and [actual] function parameters have always been a part of the language i.e. they are valid. So there is no error. You should review the topic if you don't remember them.

2785528
  • 5,438
  • 2
  • 18
  • 20