Have OpenCL and OpenGL SL got any “undefined behaviour”?-Collection of common programming errors
I was told that C and C++ have “undefined behavior”, that is, the same code might behave differently on different platforms, or using different compilers, if I use “certain constructs”.
That’s not what undefined behavior actually means. That is the result of undefined behavior, but that’s not what it’s for.
Specifications are all about defining what happens when you do something. It says what parameter values are good and which are bad. If you pass bad ones, it tells you what errors you get and what the state of the system will be. If the current state is invalid for an operation you attempt to perform, the specification explains what other kinds of errors you get and what that means for the state of the system afterwards.
When you use defined behavior, you are relying on a contract between yourself and the implementation; that contract is called the OpenGL specification. You rely on the implementation to provide the validity checks that the specification requires. And you rely on the implementation doing what the specification says. If the implementation doesn’t implement something correctly, then it is breaking the contract.
When the specification says that a certain set of things will result in “undefined behavior”, what that means is doing those things is you are breaking the contract. You are off the edge of the map. You are doing something for which the specification does not provide defined behavior; you broke your part of the deal.
To put it another way, your code will be perfectly portable as long as you don’t rely on undefined behavior. That’s what it means.
Generally, the spec marks something undefined if testing for it would be an onerous burden for implementations. OpenGL does need to be reasonably fast, after all. So burdening the driver by forcing it to test for things that would be nearly impossible to check for is something they try to avoid.
Then, there are tests which are flat-out impossible to test for. In OpenGL, it is illegal to read from and write to the same image, by binding an image as a texture and sampling from it, while simultaneously attaching that image to an FBO and rendering to it. There is no way to guaranteeably test for this scenario.
Oh, you can test for most of it. You could fail on draw calls when the same texture is bound to the FBO and to a sampler. But then, you wouldn’t be able to render to different mipmaps of the same texture; remember: each mipmap is a separate image. So you could check to see if the base/max level range allows for the possibility to sample from the mipmap that is bound to the FBO. But that puts a hefty burden on the user, as they would have to be constantly adjusting the base/max level when rendering to different mipmaps. It’s much easier for them to just sample from the correct mipmap with textureLOD
or similar functions. And you can’t determine until runtime whether they are sampling from outside that mipmap level.
OpenCL and OpenGL SL have undefined behavior, just like many specifications. And generally, it’s undefined for the same reasons: testing for it would make the implementation unacceptably slower, or testing is flat-out impossible.