O C ++ 20 exige que o código-fonte seja armazenado em arquivos?

106

Uma pergunta um pouco estranha, no entanto, se bem me lembro, o código-fonte C ++ não requer um sistema de arquivos para armazenar seus arquivos.

Ter um compilador que escaneia documentos escritos à mão por meio de uma câmera seria uma implementação adequada. Embora praticamente não faça muito sentido.

No entanto, o C ++ 20 agora adiciona o local de origem com file_name. Isso significa que o código-fonte deve sempre ser armazenado em um arquivo?

JVApen
fonte
13
Isso está em C desde sempre - __FILE__. A classe source_locationapenas permite que você acesse no local da chamada de função.
StaceyGirl
28
Você não pode dar o nome do arquivo aos seus papéis escritos à mão?
Jarod42 de
8
Acho que é um detalhe de implementação se o código-fonte está em arquivos ou em outra coisa. Se o compilador puder ser alimentado com o código-fonte por meio de stdin, a fonte pode estar em um banco de dados.
Eljay
8
Meu exemplo pode estar um pouco errado, mas se você usar algum compilador on-the-fly, como o TCC, você sempre pode fornecer algum nome de fonte legível por humanos para fins de relatório de erros, mesmo que compile diretamente da memória. Ter um "nome de arquivo" não implica em ser armazenado como um arquivo.
user7860670
2
Certamente são os arquivos de implementação como <iostream> esses podem não ser arquivos (se é que você me entende), não os arquivos escritos por desenvolvedores?

Respostas:

110

Não, o código-fonte não precisa vir de um arquivo (nem ir para um arquivo).

Você pode compilar (e vincular) C ++ completamente dentro de um pipe, colocando seu compilador no meio, por exemplo

generate_source | g++ -o- -xc++ - | do_something_with_the_binary

e tem sido assim há décadas. Veja também:

A introdução de std::source_locationem C ++ 20 não muda esse estado de coisas. Acontece que alguns códigos não terão um local de origem bem definido (ou podem ser bem definidos, mas não muito significativos). Na verdade, eu diria que a insistência em definir std::source_locationusando arquivos é um pouco míope ... embora para ser justo, é apenas um equivalente sem macro __FILE__e __LINE__que já existe em C ++ (e C).

@ HBv6 observa que se você imprimir o valor de __FILE__ao compilar usando GCC a partir do fluxo de entrada padrão:

echo -e '#include <iostream>\n int main(){std::cout << __FILE__ ;}' | g++ -xc++  -

executando as impressões executáveis ​​resultantes <stdin>.

O código-fonte pode até vir da Internet.

@Morwenn observa que este código:

#include <https://raw.githubusercontent.com/Morwenn/poplar-heap/master/poplar.h>

// Type your code here, or load an example.
void poplar_sort(int* data, size_t size) {
    poplar::make_heap(data, data + size);
    poplar::sort_heap(data, data + size);
}

funciona em GodBolt (mas não funciona em sua máquina - nenhum compilador popular suporta isso).

Você é advogado de línguas? Ok, então vamos consultar o padrão ..

A questão de saber se as origens do programa C ++ precisam vir de arquivos não é respondida claramente no padrão de linguagem. Olhando para um rascunho do padrão C ++ 17 (n4713), a seção 5.1 [lex.separate] diz:

  1. O texto do programa é mantido em unidades chamadas arquivos de origem neste documento. Um arquivo de origem junto com todos os cabeçalhos (20.5.1.2) e arquivos de origem incluídos (19.2) por meio da diretiva de pré-processamento #include, menos quaisquer linhas de origem ignoradas por qualquer uma das diretivas de pré-processamento de inclusão condicional (19.1), é chamado de unidade de tradução.

Portanto, o código-fonte não é necessariamente mantido em um arquivo em si, mas em uma "unidade chamada arquivo-fonte". Mas então, de onde vêm as inclusões? Alguém poderia supor que eles vêm de arquivos nomeados no sistema de arquivos ... mas isso também não é obrigatório.

De qualquer forma, std::source_locationnão parece mudar esta redação em C ++ 20 ou afetar sua interpretação (AFAICT).

einpoklum
fonte
9
Esse tubo é um "arquivo fonte" para os fins do padrão.
melpomene de
5
Estou olhando para o padrão C, que define: "O texto do programa é mantido em unidades chamadas arquivos de origem (ou arquivos de pré - processamento ) neste Padrão Internacional." Portanto, onde quer que o código esteja armazenado, esse é um "arquivo fonte" no Standardese. (Adendo: linguagem semelhante é encontrada no padrão C ++ em [lex].)
melpomene
8
@melpomene: As unidades são chamadas apenas de arquivos de origem, não diz que eles realmente precisam ser arquivos de origem. Mas vou editar a resposta para incluir isso.
einpoklum de
13
Apenas tentei isso com GCC: "echo '#include <stdio.h> \ nint main () {printf ("% s \\ n ", __FILE__); return 1;}' | gcc -o test -xc -" ( sem aspas). Quando executado, ele imprime <stdin>.
HBv6
11
Aqui está uma coisa engraçada sobre termos, nomes e conceitos em padrões (e ciências): eles geralmente são atômicos. Ou seja, "arquivo de origem" não é necessariamente um "arquivo" que é "fonte", na verdade, o termo "arquivo" pode simplesmente não ser definido - compare com os números na matemática: não existe apenas um " número ", apenas" número natural "," número racional "," número real ", etc.
Joker_vD
53

Mesmo antes do C ++ 20, o padrão tinha:

__FILE__

O nome presumido do arquivo de origem atual (uma cadeia de caracteres literal).

A definição é a mesma para source_location::file_name.

Como tal, não houve uma mudança em relação ao suporte para implementações sem sistema de arquivos em C ++ 20.

O padrão não define exatamente o que "arquivo de origem" significa, então se ele se refere a um sistema de arquivos pode ser uma interpretação. Presumivelmente, pode estar em conformidade com uma implementação para produzir "a nota manuscrita que você me deu naquele momento", se isso realmente identificar o "arquivo de origem" nessa implementação da linguagem.


Concluindo: Sim, as origens são chamadas de "arquivos" pelo padrão, mas o que é um "arquivo" e se um sistema de arquivos está envolvido não é especificado.

Eerorika
fonte
2
@Yksisarvinen Não sei exatamente a intenção da qualificação de "presunção" da regra, mas presumo :) que é um esclarecimento de que o nome do arquivo precisa ser absoluto ou canônico, mas sim um nome relativo da perspectiva de o compilador é suficiente. Eu poderia estar errado.
eerorika
4
Posso ver o scanner-c++retorno de "Armário esquerdo, terceira gaveta, quarta pasta com abas vermelhas, página 17" .
dmckee --- ex-moderador gatinho de
2
FWIW, no sentido POSIX, um pipe (ou qualquer outra coisa semelhante a um arquivo) é um "arquivo" - como tal, stdin / stdout são "arquivos", mas não arquivos de disco, etc. neste sentido.
3
@Yksisarvinen: O Comitê freqüentemente permite situações em que implementações obscuras podem ter bons motivos para fazer algo contrário ao comportamento comum. Ao fazer isso, ele depende de redatores de compiladores para julgar se seus clientes considerariam o comportamento comum mais ou menos útil do que alguma alternativa. O fato de essas coisas serem deixadas para o julgamento dos implementadores pode ser visto como uma "ambigüidade", mas é deliberada, uma vez que bons redatores de compiladores saberão mais sobre as necessidades de seus clientes do que o Comitê jamais poderia.
supercat
1
@dmckee ... em um banheiro desativado com uma placa na porta dizendo 'Cuidado com o leopardo. ”
Andrew Henle de