Venho armando meu mecanismo com código de verificação de erro. Vou tentar descrever essa situação com minhas melhores habilidades. Sempre que carrego um sombreador e há um erro (arquivo não existe, erro de compilação, qualquer coisa que possa dar errado) eu excluo o sombreador e defino o ponteiro como 0 (não consigo pensar em outra maneira de garantir que não tente anexar ou excluir lixo por acidente). Não quero interromper o programa se isso acontecer, porque alguém pode excluir ou modificar um único arquivo por acidente na pasta do jogo e não deseja tornar o jogo inteiro inutilizável por causa disso.
Agora, o problema é que existe um comportamento padrão na situação em que anexo shaders a um programa que tem o ponteiro igual a 0?
No meu programa, se eu anexar um shader de vértice igual a 0 e um shader de fragmento igual a 0, o OpenGL usará o programa padrão (exibirá tudo em branco):

Este é um cubo girado cujas dimensões já estão no espaço do clipe, renderizadas sem projeção em perspectiva ou verificação de profundidade. É carregado de um arquivo .obj.
Agora, se eu anexar um shader de fragmento adequado, mas o shader de vértice será 0, recebo o seguinte:

Qual é o que eu esperaria, tudo que o shader de fragmento faz é gerar um vec4 (1.0, 0.3, 0.7, 1.0), não há shader de vértice, então o OpenGL usa o padrão (essa é uma suposição correta?).
Agora, no entanto, se eu anexar um shader de vértice correto, mas anexar um shader de fragmento igual a 0 (ou não anexarei nenhum shader de fragmento), vou receber essa bagunça:

Algo que você não pode ver é que esse modelo está sendo pintado de cores diferentes, então, na minha tela, parece uma viagem ácida com linhas horizontais pretas.
Estou um pouco confuso, porque eu esperaria que o cubo fosse apenas branco. Gostaria de ressaltar que meu código de sombreador é simples, não estou trocando nenhuma variável entre sombreadores de vértice e fragmentos. Verificando se o ponteiro não é igual a 0 não muda nada, o programa vinculado age da mesma forma que se eu desse um ponteiro igual a 0. O mais estranho para mim é que ele sempre está bem sombreado, não é apenas lixo.
EDIT: Talvez o shader de fragmento padrão espera um valor gl_ do vértice que eu estou omitindo para definir? Isso meio que explica por que a superfície é bem sombreada, o sombreador de fragmento espera uma entrada suave, mas esse valor é apenas lixo, porque eu não o defini.
Agora, esse é um "comportamento indefinido" ou é assim que é suposto funcionar?