OpenGL 4 リファレンス ページに示されているように、OpenGL ドライバーがシェーダー データが null で終了していると想定できる状況が 2 つあります。
glShaderSourceドキュメントから:
length
である場合NULL
、各文字列は null で終了すると見なされます。length
が 以外の値の場合、NULL
の対応する各要素の文字列の長さを含む配列を指しstring
ます。長さ配列の各要素には、対応する文字列の長さ (null 文字は文字列の長さの一部としてカウントされません)、または文字列が null で終了することを示す 0 未満の値を含めることができます。この時点では、ソース コード文字列はスキャンまたは解析されません。これらは、指定されたシェーダー オブジェクトに単純にコピーされます。
強調された制約はどちらも提示された状況には当てはまらないため、ドライバーは、strlen
提供されたデータに対して直接のような安全でない c-string 関数を使用することはできません。その場合、データの最後を超えて実行され、おそらく最終的に未割り当てのメモリにアクセスして、プログラムをクラッシュさせる可能性があります。
ただし、ドライバーはデータのコピーを安全なバッファーに作成し、それを呼び出すstrlen
ことができます。たとえば、実装には次のようなコードが含まれる場合があります。
void glShaderSource(GLuint shader,
GLsizei count,
const GLchar **string,
const GLint *length)
{
if (length == NULL) { /* each string is null terminated. */ }
else for (GLsizei i = 0; i < count; ++i)
{
size_t len = length[i];
if (len < 0) { /* this string is null terminated. */ }
else
{
char* buffer = (char*)malloc(len + 1);
memcpy(buffer, string[i], len);
buffer[len] = 0;
size_t str_len = strlen(buffer);
// This is OK, because we copied the
// data into a null terminated buffer.
free(buffer);
}
}
}
したがって、この場合、ドライバーが実際にユーザー提供のポインターを呼び出してstrlen
いる場合、それは OpenGL 仕様に違反しており、プログラムのクラッシュを引き起こす可能性があります。ユーザーが提供した文字列が渡されます。strlen
glShaderSource
少し関係の深い話ですが、明示的な長さで提供される文字列内にヌル文字が存在する場合に何が起こるかは、標準では指定されていません。つまり、実装は好きなように行うことができます。文字列を null で終了する (したがって、その後のすべてをスキップする) として扱うか、null 文字を無視するか、または GLSL によって空白として認識される文字の中にないため、シェーダーのコンパイルが失敗する可能性があります。