1

I'm currently learning OpenGL, I'm also fairly new to C++. My question that I have is why is a pointer used here.

GLFWwindow *mainWindow = glfwCreateWindow(WIDTH, HEIGHT, "Test Window", NULL, NULL);

I get what pointers are, just not why they are used here. All answers are appreciated, thanks.

BeastCoder
  • 2,391
  • 3
  • 15
  • 26
  • 3
    "Why do we use pointers when declaring a variable with a value that is a function". The value is not a function. That would be a function pointer. Here you CALL a function that returns a pointer to a window handle structure. Since the function returns a struct, it has to be stored somewhere. The chosen approach here is to create the structure somewhere (on the heap) and return a pointer to it. – Dr Phil Sep 17 '19 at 22:40
  • @DrPhil So it returns a C++ structure, which we need a pointer to because we can't really have a variable store a structure. With the pointer we can then axis everything we need. Is that correct? P.S. nice name – BeastCoder Sep 17 '19 at 22:43
  • 2
    _I understand exactly what the code does._ No, you don't. – Thomas Sablik Sep 17 '19 at 22:44
  • @ThomasSablik good point :) – BeastCoder Sep 17 '19 at 22:45
  • 1
    "we can't really have a variable store a structure." - we can (e.g. a `std::string`) but the designers of this interface decided to go with pointers – M.M Sep 17 '19 at 22:47
  • 3
    You can return a copy of an object in a function and store it in a variable. But in this case you don't want a copy of a window handle. You want a reference (pointer) to specific window handle. – Thomas Sablik Sep 17 '19 at 22:47
  • @ThomasSablik Thanks, that is a great explanation! – BeastCoder Sep 17 '19 at 22:49
  • Note that while the handle is probably sitting on the heap, don't try to `delete` it yourself. Call `glfwDestroyWindow` to dispose of it when you are done. It might not have been `new`ed and Crom only know what other book-keeping lurks in the back-end. – user4581301 Sep 17 '19 at 23:52

2 Answers2

1

There is no inherent necessity for a glfwCreateWindow() to return a pointer-to-a window, rather than an actual window. The OpenGL library could possibly have been designed so that that code would look different, e.g.:

GLFWwindow mainWindow = glfwCreateWindow(WIDTH, HEIGHT, "Test Window", nullptr, nullptr);

or in fact, just using a construction of a GLFWindow:

GLFWwindow mainWindow { WIDTH, HEIGHT, "Test Window", nullptr, nullptr }; 

still, there are several possible reasons why the API was designed this way:

  1. Until C++ 2017, compilers were not required to perform RVO - return value optimization. That meant that if your function returns a value of type T, you could theoretically need to copy the T you create within the function to the destination location at the code which called the function. In your case - returning a GLFWwindow might have required making a copy of the GLFWwindow; and that could possibly have been problematic for the library (I don't know OpenGL so I have no idea).
  2. When your function returns a T*, the pointed-to object can be anything that "is a T" - which means any type that inherits from T (!); while if you return a plain T - you can't return inheriting types. So if there is a class hierarchy of GLFWwindows, all inheriting from GLFWwindow as a base class - it can make sense to to return a pointer to that base class, for you to handle generically.

PS - Having five constructor parameters, and passing arguments which make it rather unclear what constructor parameter is being set, is problematic design. Specifically - we can't tell what the first nullptr signifies, nor how it differs from the second nullptr.

einpoklum
  • 118,144
  • 57
  • 340
  • 684
-1
  1. You need a reference to the window directly to make changes to it.
  2. If it returns a C++ structure and the definition of the structure is like :
    struct someStructure{
        int width;
        int length;
        string name;
        //some more variables
    }

then at the time of passing this structure to any function/method - you will be passing
[ sizeof(int) + sizeof(int) + sizeof(string) +...+ sizeof(int)] bytes of data - which is say 64 bytes (which can also increase with time as you modify/alter your structure.

But if you pass the pointer reference instead, it only sends an address (8bit/16bit/32bit etc.. ) which would depend on your system addressing scheme, it will be fixed and won't change even if you add more members to your structure in future.

vS12
  • 310
  • 2
  • 8