C ++ 20 có bắt buộc mã nguồn được lưu trữ trong tệp không?


106

Tuy nhiên, một câu hỏi hơi kỳ lạ, nếu tôi nhớ không nhầm thì mã nguồn C ++ không yêu cầu hệ thống tệp để lưu trữ các tệp của nó.

Có một trình biên dịch quét các giấy tờ viết tay qua camera sẽ là một cách triển khai phù hợp. Mặc dù thực tế không có nhiều ý nghĩa.

Tuy nhiên C ++ 20 bây giờ thêm vị trí nguồn với file_name. Điều này có ngụ ý rằng mã nguồn phải luôn được lưu trữ trong một tệp không?


13
Điều này đã có trong C từ mãi mãi - __FILE__. Lớp source_locationchỉ cho phép bạn lấy nó tại trang web gọi hàm.
StaceyGirl

28
Bạn không thể đặt tên tệp cho giấy tờ viết tay của mình?
Jarod42

8
Tôi nghĩ rằng đó là một chi tiết triển khai cho dù mã nguồn nằm trong tệp hay thứ gì khác. Nếu trình biên dịch có thể được cung cấp mã nguồn thông qua stdin, thì nguồn có thể nằm trong cơ sở dữ liệu.
Eljay

8
Ví dụ của tôi có thể hơi sai, nhưng nếu bạn sử dụng một số trình biên dịch trực tuyến, chẳng hạn như TCC, bạn luôn có thể cung cấp một số tên nguồn có thể đọc được của con người để báo lỗi ngay cả khi bạn biên dịch trực tiếp từ bộ nhớ. Đó là có một "tên tệp" không có nghĩa là được lưu trữ dưới dạng tệp.
user7860670

2
Chắc chắn đó là các tệp triển khai chẳng hạn như <iostream> đó có thể không phải là tệp (nếu bạn hiểu ý tôi), không phải tệp được viết bởi các nhà phát triển?

Câu trả lời:


110

Không, mã nguồn không nhất thiết phải đến từ một tệp (cũng không phải đến một tệp).

Bạn có thể biên dịch (và liên kết) C ++ hoàn toàn trong một đường ống, đặt trình biên dịch của bạn ở giữa, ví dụ:

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

và nó đã như vậy trong nhiều thập kỷ. Xem thêm:

Sự ra đời của std::source_locationC ++ 20 không thay đổi trạng thái này. Chỉ là một số mã sẽ không có vị trí nguồn được xác định rõ ràng (hoặc nó có thể được xác định rõ ràng, nhưng không có ý nghĩa lắm). Trên thực tế, tôi muốn nói rằng sự khăng khăng về việc xác định std::source_locationbằng cách sử dụng các tệp là hơi hoang đường ... mặc dù công bằng mà nói, nó chỉ là một tương đương ít macro __FILE____LINE__đã tồn tại trong C ++ (và C).

@ HBv6 lưu ý rằng nếu bạn in giá trị của __FILE__khi biên dịch bằng GCC từ luồng đầu vào chuẩn:

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

chạy các bản in thực thi kết quả <stdin>.

Mã nguồn thậm chí có thể đến từ Internet.

@Morwenn lưu ý rằng mã này:

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

hoạt động trên GodBolt (nhưng sẽ không hoạt động trên máy của bạn - không có trình biên dịch phổ biến nào hỗ trợ điều này.)

Bạn là một luật sư ngôn ngữ? Ok, vậy cùng tham khảo chuẩn ..

Câu hỏi liệu nguồn chương trình C ++ có cần đến từ các tệp hay không không được trả lời rõ ràng trong tiêu chuẩn ngôn ngữ. Nhìn vào bản nháp của tiêu chuẩn C ++ 17 (n4713), phần 5.1 [lex.separate] đọc:

  1. Văn bản của chương trình được giữ trong các đơn vị được gọi là tệp nguồn trong tài liệu này. Một tệp nguồn cùng với tất cả các tiêu đề (20.5.1.2) và tệp nguồn được bao gồm (19.2) thông qua chỉ thị tiền xử lý #include, trừ đi bất kỳ dòng nguồn nào bị bỏ qua bởi bất kỳ chỉ thị tiền xử lý bao gồm có điều kiện (19.1) nào, được gọi là đơn vị dịch.

Vì vậy, mã nguồn không nhất thiết phải được giữ trong một tệp, nhưng trong một "đơn vị được gọi là tệp nguồn". Nhưng sau đó, bao gồm đến từ đâu? Người ta sẽ cho rằng chúng đến từ các tệp được đặt tên trên hệ thống tệp ... nhưng điều đó cũng không bắt buộc.

Ở bất kỳ mức độ nào, std::source_locationdường như không thay đổi từ ngữ này trong C ++ 20 hoặc ảnh hưởng đến cách diễn giải của nó (AFAICT).


9
Đường ống đó là một "tệp nguồn" cho các mục đích của tiêu chuẩn.
melpomene

5
Tôi đang xem tiêu chuẩn C, định nghĩa: "Văn bản của chương trình được lưu giữ trong các đơn vị được gọi là tệp nguồn , (hoặc tệp tiền xử lý ) trong Tiêu chuẩn này." Vì vậy, bất cứ nơi nào mã được lưu trữ, đó là "tệp nguồn" trong Standardese. (Phụ lục: Ngôn ngữ tương tự được tìm thấy trong tiêu chuẩn C ++ theo [lex].)
melpomene

8
@melpomene: Các đơn vị chỉ được gọi là tệp nguồn, nó không nói rằng chúng thực sự phải là tệp nguồn. Nhưng tôi sẽ chỉnh sửa câu trả lời để bao gồm điều này.
einpoklum

13
Vừa thử điều này với GCC: "echo '#include <stdio.h> \ nint main () {printf ("% s \\ n ", __FILE__); return 1;}' | gcc -o test -xc -" ( không có dấu ngoặc kép). Khi được thực thi, nó sẽ in ra <stdin>.
HBv6

11
Đây là một điều thú vị về các thuật ngữ và tên gọi và khái niệm trong các tiêu chuẩn (và khoa học): chúng thường là nguyên tử. Có nghĩa là, "tệp nguồn" không nhất thiết phải là "tệp" mà là "nguồn", trên thực tế, thuật ngữ "tệp" có thể đơn giản là không được định nghĩa - so sánh với các con số trong phép toán: không có cái gọi là " number ", chỉ" nmber tự nhiên "," số hữu tỉ "," số thực ", v.v.
Joker_vD 19/08/19

53

Ngay cả trước C ++ 20, tiêu chuẩn đã có:

__FILE__

Tên giả định của tệp nguồn hiện tại (một chuỗi ký tự theo nghĩa đen).

Định nghĩa giống nhau đối với source_location::file_name.

Do đó, không có thay đổi nào liên quan đến việc hỗ trợ triển khai hệ thống tệp trong C ++ 20.

Tiêu chuẩn không xác định chính xác "tệp nguồn" nghĩa là gì, vì vậy việc nó đề cập đến hệ thống tệp có thể tùy thuộc vào cách giải thích. Có lẽ, nó có thể phù hợp để triển khai tạo ra "ghi chú viết tay mà bạn đã đưa cho tôi ngay lúc đó" nếu điều đó thực sự xác định được "tệp nguồn" trong việc triển khai ngôn ngữ đó.


Kết luận: Vâng, các nguồn được gọi là "tệp" theo tiêu chuẩn, nhưng "tệp" là gì và liệu hệ thống tệp có liên quan hay không thì chưa được xác định.


2
@Yksisarvinen Tôi không biết chính xác ý định về tiêu chuẩn "giả định" của quy tắc, nhưng tôi đoán :) rằng cần làm rõ rằng tên tệp cần phải là tuyệt đối hoặc chuẩn, nhưng đúng hơn là một tên tương đối theo quan điểm của trình biên dịch là đủ. Tôi có thể sai.
eerorika

4
Tôi chỉ có thể thấy scanner-c++trả về "Tủ bên trái, ngăn thứ ba, thư mục tab đỏ thứ tư, trang 17" .
dmckee --- ex-moderator kitten,

2
FWIW, theo nghĩa POSIX, một đường ống (hoặc bất kỳ thứ gì khác của tệp) là một "tệp" - như vậy, stdin / stdout là "tệp", chỉ không phải tệp đĩa, v.v. theo nghĩa này.

3
@Yksisarvinen: Ủy ban thường cho phép đối với những tình huống mà việc triển khai không rõ ràng có thể có lý do chính đáng để làm điều gì đó trái với hành vi thông thường. Khi làm như vậy, nó dựa vào người viết trình biên dịch để đánh giá liệu khách hàng của họ sẽ thấy hành vi phổ biến hữu ích hơn hay ít hơn so với một số hành vi thay thế. Thực tế là những điều như vậy để người thực hiện đánh giá có thể được xem là "sự mơ hồ", nhưng đó là một điều có chủ ý, vì những người viết biên dịch giỏi sẽ biết nhiều hơn về nhu cầu của khách hàng của họ hơn bao giờ hết.
supercat

1
@dmckee ... trong một nhà vệ sinh không sử dụng với tấm biển trên cửa ghi 'Hãy coi chừng loài báo.'
Andrew Henle
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.