Search code examples
c++functionconventionsxcode

Setting Default Parameters in C++


I have a little question about how default values are given to function parameters in C++. The problem I faced is probably due to my lack of understanding as to where the parameters are supposed to be declared/defined in the function prototype or the function header, or both? Codes are below with the errors noted:

#include <iostream>

using namespace std;

float volume(float l, float w, float h);

int main() {

    float length;
    float width;
    float height;

    cout << volume() << endl; // Here, with 'volume()' underlined, it says:
    //no matching function for call to 'volume()'

    cout << "Length: ";
    cin >> length;

    cout << "Width: ";
    cin >> width;

    cout << "Height: ";
    cin >> height;

    cout << "Volume = " << volume(length, width, height) << endl;


}

float volume(float l = 1, float w = 1, float h = 1){

        float vol = l * w * h;

    return vol;
}

In another attempt, here's what happened:

#include <iostream>

using namespace std;

float volume(float l = 1, float w = 1, float h = 1);

int main() {

    float length;
    float width;
    float height;

    cout << volume() << endl;

    cout << "Length: ";
    cin >> length;

    cout << "Width: ";
    cin >> width;

    cout << "Height: ";
    cin >> height;

    cout << "Volume = " << volume(length, width, height) << endl;


}

float volume(float l = 1, float w = 1, float h = 1){ //Here, Xcode says that
// that the error is: Redefinition of default argument. < which I believe I understand.

        float vol = l * w * h;

    return vol;
}

In my last attempt, which is the one that worked, I did this:

#include <iostream>

using namespace std;

float volume(float l = 1, float w = 1, float h = 1);

int main() {

    float length;
    float width;
    float height;

    cout << volume() << endl;

    cout << "Length: ";
    cin >> length;

    cout << "Width: ";
    cin >> width;

    cout << "Height: ";
    cin >> height;

    cout << "Volume = " << volume(length, width, height) << endl;


}

float volume(float l, float w, float h){

        float vol = l * w * h;

    return vol;
}

Could someone please explain to me the logic behind why the latter worked while the first two did not? Is there another way that the code would still work in the same way with the parameters specified elsewhere or the default values set in some place else? Are there any conventions or more favored practices in this area?

Adam


Solution

  • C++ and C are parsed top-down. When the compiler interprets a statement, it doesn't know about things it hasn't read yet.

    In your first example, you declare a function called "volume", prototyped as taking 3 floats and returning a float. You then try to call a function called "volume" that takes no parameters, which doesn't exist yet (it would be a different function, since C++ supports polymorphism). You later define a function that can take 0, 1, 2, or 3 floats, but it is both too late and has an incompatible prototype to the first.

    Your second example intuitively makes sense to be wrong, kind of like defining variables twice, but I don't have any specific information about why it is invalid code when the default values are identical.

    Default parameters must be specified in the function prototype, which must occur prior to first usage in order for the compiler to know about it. Typically, you would put the prototypes with their default values in a header file that gets included above the code.

    One thing to watch out for when dealing with default parameters from a shared header file, especially if you use it with dynamic libraries: The default values for the parameters are stored with the caller, and not the function being called. That is, if you update the function with new default values and don't rebuild the code calling that function, the old defaults will still be used by the calling code.