To be honestly I didn't know how to add checking return values. :P Maybe because I don't know exactly what do you mean. :P
It's literally checking values returned from the function calls that you perform.
Let's take "vertex = glCreateShader(GL_VERTEX_SHADER);" You assign it to "vertex". However, if you check what the function actually does:
https://www.khronos.org/registry/OpenGL-Refpages/es2.0/xhtml/glCreateShader.xml
The "C Specification" section says
GLuint glCreateShader(GLenum shaderType);
so GLuint is presumably the type of 'vertex'. So far so good. Also, the "Errors" section says
This function returns 0 if an error occurs creating the shader object.
GL_INVALID_ENUM is generated if shaderType is not an accepted value.
Thus, if your vertex == 0, you don't have a vertex, since the call failed to create one.
Similarly, it may fail if you provide a wrong shader value, but GL_VERTEX_SHADER is in the list accepted argument values, so that should be alright.
Checking return values here means, verifying that "vertex" is not 0, since in that case, you don't actually have a vertex.
Thus:
vertex = glCreateShader(GL_VERTEX_SHADER);
if (vertex == 0) {
fprintf(stderr, "Vertex shader creation failed\n");
exit(1);
}
and that's about it. Now each time you run the code, the computer checks that the call didn't fail, so your "vertex" variable actually contains a usable vertex number.
In C++ things don't stop if it fails, unless you code that.
Instead, it will happily continue computing all next code, if you're lucky, it will hard-crash at some spot so you have a point where you can start figuring out what went wrong. If you're unlucky, the result is not what you expect. The really unlucky case is that the output seems correct, but it isn't. That kind of errors can hide for a very very long time.