Czy C ++ 20 wymaga przechowywania kodu źródłowego w plikach?

106

Jednak nieco dziwne pytanie, jeśli dobrze pamiętam, kod źródłowy C ++ nie wymaga systemu plików do przechowywania plików.

Posiadanie kompilatora, który skanuje odręczne dokumenty za pomocą aparatu, byłoby zgodną implementacją. Chociaż praktycznie nie ma to większego sensu.

Jednak C ++ 20 dodaje teraz lokalizację źródłową z file_name. Czy to teraz oznacza, że ​​kod źródłowy powinien być zawsze przechowywany w pliku?

JVApen
źródło
13
To było w C od zawsze - __FILE__. Klasa source_locationpo prostu pozwala ci ją pobrać na stronie wywołania funkcji.
StaceyGirl
28
Nie możesz nadać nazwy pliku swoim odręcznym dokumentom?
Jarod42
8
Myślę, że to szczegół implementacji, czy kod źródłowy jest w plikach, czy coś innego. Jeśli kompilator może otrzymać kod źródłowy przez stdin, źródło może znajdować się w bazie danych.
Eljay
8
Mój przykład może być trochę dziwny, ale jeśli używasz jakiegoś kompilatora działającego w locie, takiego jak TCC, zawsze możesz podać jakąś czytelną dla człowieka nazwę źródła w celu raportowania błędów, nawet jeśli kompilujesz bezpośrednio z pamięci. To, że posiadanie „nazwy pliku” w ogóle nie oznacza, że ​​jest on przechowywany jako plik.
user7860670
2
Z pewnością są to pliki wdrożeniowe, takie jak te, <iostream> które mogą nie być plikami (jeśli widzisz, o co mi chodzi), a nie plikami napisanymi przez programistów?

Odpowiedzi:

110

Nie, kod źródłowy nie musi pochodzić z pliku (ani przechodzić do pliku).

Możesz skompilować (i połączyć) C ++ całkowicie w potoku, umieszczając kompilator pośrodku, np

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

i tak jest od dziesięcioleci. Zobacz też:

Wprowadzenie std::source_locationw C ++ 20 nie zmienia tego stanu rzeczy. Po prostu jakiś kod nie będzie miał dobrze zdefiniowanej lokalizacji źródłowej (lub może być dobrze zdefiniowana, ale niezbyt znacząca). Właściwie, to powiedziałbym, że nacisk na definiowanie std::source_locationza pomocą plików jest nieco krótkowzroczny ... chociaż w sprawiedliwości, to jest po prostu mniej makro odpowiednik __FILE__i __LINE__które już istnieją w C ++ (i C).

@ HBv6 zauważa, że ​​jeśli wypiszesz wartość __FILE__podczas kompilacji przy użyciu GCC ze standardowego strumienia wejściowego:

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

uruchamianie wynikowych wydruków wykonywalnych <stdin>.

Kod źródłowy może nawet pochodzić z Internetu.

@Morwenn zauważa, że ​​ten kod:

#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);
}

działa na GodBolt (ale nie będzie działać na twoim komputerze - żaden popularny kompilator tego nie obsługuje).

Czy jesteś prawnikiem językowym? Ok, więc zapoznajmy się ze standardem.

Na pytanie, czy źródła programów C ++ muszą pochodzić z plików, nie ma jednoznacznej odpowiedzi w standardzie językowym. Patrząc na szkic standardu C ++ 17 (n4713), sekcja 5.1 [lex.separate] brzmi:

  1. Tekst programu jest przechowywany w jednostkach zwanych plikami źródłowymi w tym dokumencie. Plik źródłowy wraz ze wszystkimi nagłówkami (20.5.1.2) i plikami źródłowymi (19.2) zawartymi przez dyrektywę preprocessingu #include, pomijając wszelkie linie źródłowe pominięte przez którąkolwiek z dyrektyw wstępnego przetwarzania warunkowego włączenia (19.1), nazywany jest jednostką tłumaczenia.

Zatem kod źródłowy niekoniecznie jest przechowywany w pliku jako takim, ale w „jednostce zwanej plikiem źródłowym”. Ale skąd się biorą dołączenia? Można by przypuszczać, że pochodzą z nazwanych plików w systemie plików ... ale to też nie jest wymagane.

W każdym razie std::source_locationnie wydaje się zmieniać tego sformułowania w C ++ 20 ani wpływać na jego interpretację (AFAICT).

einpoklum
źródło
9
Ten potok jest „plikiem źródłowym” na potrzeby standardu.
melpomene
5
Patrzę na standard C, który definiuje: „Tekst programu jest przechowywany w jednostkach zwanych plikami źródłowymi (lub plikami wstępnego przetwarzania ) w tym standardzie międzynarodowym”. Więc gdziekolwiek jest przechowywany kod, jest to „plik źródłowy” w Standardese. (Dodatek: Podobny język można znaleźć w standardzie C ++ pod [lex].)
melpomene
8
@melpomene: Jednostki nazywane są po prostu plikami źródłowymi, nie mówi się, że w rzeczywistości muszą to być pliki źródłowe. Ale edytuję odpowiedź, aby to uwzględnić.
einpoklum
13
Właśnie wypróbowałem to z GCC: "echo '#include <stdio.h> \ nint main () {printf ("% s \\ n ", __FILE__); return 1;}' | gcc -o test -xc -" ( bez cytatów). Po uruchomieniu wypisuje <stdin>.
HBv6
11
Oto zabawna rzecz dotycząca terminów, nazw i pojęć w standardach (i naukach ścisłych): są one zwykle atomowe. Oznacza to, że „plik źródłowy” niekoniecznie musi być „plikiem”, który jest „źródłem”, w rzeczywistości termin „plik” może po prostu nie zostać zdefiniowany - porównaj z liczbami w matematyce: nie ma czegoś takiego jak „ liczba ”, tylko„ liczba naturalna ”,„ liczba wymierna ”,„ liczba rzeczywista ”itp.
Joker_vD
53

Jeszcze przed C ++ 20 standard miał:

__FILE__

Przypuszczalna nazwa bieżącego pliku źródłowego (literał ciągu znaków).

Definicja jest taka sama dla source_location::file_name.

W związku z tym nie nastąpiła zmiana w zakresie obsługi implementacji bez systemu plików w C ++ 20.

Standard nie definiuje dokładnie, co oznacza „plik źródłowy”, więc interpretacja może zależeć od tego, czy odnosi się on do systemu plików. Przypuszczalnie mogłoby to oznaczać, że implementacja tworzy „odręczną notatkę, którą mi wtedy przekazałeś”, jeśli rzeczywiście identyfikuje ona „plik źródłowy” w tej implementacji języka.


Podsumowując: tak, źródła są standardowo określane jako „pliki”, ale czym jest „plik” i czy w grę wchodzi system plików, nie jest określone.

eerorika
źródło
2
@Yksisarvinen Nie znam dokładnie intencji określenia „domniemania” reguły, ale zakładam :) że jest to wyjaśnienie, że nazwa pliku musi być absolutna lub kanoniczna, ale raczej nazwa względna z perspektywy kompilator jest wystarczający. Mogę się mylić.
eerorika
4
Widzę tylko scanner-c++powracający napis „Lewa szafka, trzecia szuflada, czwarty folder z czerwonymi zakładkami, strona 17” .
dmckee --- ex-moderator kitten
2
FWIW, w sensie POSIX, potok (lub jakakolwiek inna rzecz plikowa) jest "plikiem" - jako takie, stdin / stdout to "pliki", a nie pliki dyskowe itp. W tym sensie.
3
@Yksisarvinen: Komitet często uwzględnia sytuacje, w których niejasne implementacje mogą mieć dobre powody, by zrobić coś sprzecznego z powszechnym zachowaniem. Czyniąc to, polega na pisarzach kompilatorów, którzy oceniają, czy ich klienci uznaliby powszechne zachowanie za bardziej lub mniej przydatne niż jakaś alternatywa. Fakt, że takie rzeczy są pozostawione ocenie wykonawców, może być postrzegany jako „niejednoznaczność”, ale jest to kwestia celowa, ponieważ dobrzy autorzy kompilatorów będą wiedzieć więcej o potrzebach swoich klientów niż Komitet kiedykolwiek mógł.
supercat
1
@dmckee ... w nieużywanej toalecie z tabliczką na drzwiach z napisem „Uwaga na lamparta”.
Andrew Henle