Điều gì xảy ra nếu hành vi C ++ không xác định đáp ứng hành vi được xác định C?


10

Tôi có một *.cpptệp mà tôi biên dịch bằng C ++ (không phải là trình biên dịch C). Hàm chứa dựa trên một nhóm (xem dòng cuối cùng) dường như được xác định trong C (vui lòng sửa nếu tôi sai!), Nhưng không phải trong C ++ cho loại đặc biệt này.

[...] C++ code [...]

struct sockaddr_in sa = {0};
int sockfd = ...;
sa.sin_family = AF_INET;
sa.sin_port = htons(port);
bind(sockfd, (struct sockaddr *)&sa, sizeof sa);

[...] C++ code [...]

Vì tôi biên dịch tệp này trong tệp C ++, giờ đây là hành vi được xác định hoặc không xác định? Hoặc tôi sẽ cần phải di chuyển nó vào một *.ctập tin, để làm cho nó được xác định hành vi?


1
Phần mở rộng tập tin không có ý nghĩa; chỉ khi bạn biên dịch nó thành C hoặc C ++.
Fredrik

1
Các loại tương ứng không được kế thừa từ nhau và không có mối quan hệ nào và điều đó không được xác định trong C ++
Daniel Stephens

1
Thông thường, nếu tệp có .cphần mở rộng, trình biên dịch C sẽ được gọi tự động.
Igor R.

1
Tôi thực hiện thủ thuật đó mọi lúc trong mã C ++. Không biết tại sao nó sẽ không làm việc cho bạn. Thiếu một tiêu đề ở đâu đó?
dùng4581602

3
@DanielStephens Chương trình này không bao giờ cố gắng xóa con trỏ. Cast chính nó được cho phép , hội nghị - chỉ đôi khi. Nếu bên C đưa con trỏ trở lại kiểu thực thì mọi thứ sẽ ổn. Các vấn đề với việc đúc có thể xảy ra nếu các loại đó có các yêu cầu căn chỉnh khác nhau.
dùng7860670

Câu trả lời:


6

Điều này được định nghĩa trong cả C ++ và C. Nó không vi phạm các quy định răng cưa nghiêm ngặt vì nó không làm mất đi con trỏ kết quả.

Đây là trích dẫn từ C ++ (nhờ @interjay và @VTT) cho phép điều này:

Một con trỏ đối tượng có thể được chuyển đổi rõ ràng thành một con trỏ đối tượng thuộc loại khác.

Đây là trích dẫn từ C (cảm ơn @StoryTeller) cho phép điều này:

Một con trỏ tới một loại đối tượng có thể được chuyển đổi thành một con trỏ thành một loại đối tượng khác.

Chúng xác định rằng một loại con trỏ có thể được chuyển đổi sang loại con trỏ khác (và sau đó tùy ý chuyển đổi trở lại) mà không có kết quả.

Và đây là trích dẫn từ POSIX cho phép trường hợp cụ thể này:

Các sockaddr_in cấu trúc được sử dụng để lưu trữ các địa chỉ cho gia đình địa chỉ Internet. Các con trỏ tới loại này sẽ được các ứng dụng chuyển sang struct sockaddr * để sử dụng với các chức năng của socket.

Vì hàm này ( bind) là một phần của thư viện chuẩn C, nên bất cứ điều gì diễn ra bên trong (cụ thể là, bỏ hội thảo con trỏ đúc kiểu) không có hành vi không xác định.


Để trả lời câu hỏi chung chung hơn:

C và C ++ là hai ngôn ngữ khác nhau. Nếu một cái gì đó được định nghĩa trong C nhưng không phải trong C ++, thì nó được định nghĩa trong C nhưng không phải trong C ++. Không có sự tương thích ngụ ý giữa hai ngôn ngữ sẽ thay đổi điều đó. Nếu bạn muốn sử dụng mã được xác định rõ trong C nhưng không được xác định trong C ++, bạn sẽ phải sử dụng trình biên dịch C để biên dịch mã đó.


1
@interjay Bạn có thể sao lưu điều đó bằng một trích dẫn từ tiêu chuẩn (C hoặc C ++ vẫn ổn)?
SS Anne


1
@StoryTeller Cảm ơn. Đã thêm phiên bản HTTP thay vào đó.
SS Anne

2
Có thể cho rằng đây là một khiếm khuyết trong tiêu chuẩn POSIX - đối số thứ hai bindphải là một const void *, nhưng bindcó trước sự tồn tại của voidngôn ngữ C (và sự tồn tại của C ++). Họ đã cập nhật nó tại một số điểm để thêm const, nhưng không bao giờ sửa loại cơ bản.
Chris Dodd

1
Tôi có thể giới thiệu bài nói chuyện này youtube.com/watch?v=_qzMpk-22cc Tôi vẫn không chắc liệu nó có xác thực câu trả lời hay không, nếu nó thực sự nói ngược lại: -o C ++ là một cơn ác mộng .. lol
Daniel Stephens

-3

Các cuộc gọi giữa mã C và C ++ đều gọi Hành vi không xác định, theo quan điểm của các tiêu chuẩn tương ứng, nhưng hầu hết các nền tảng đều chỉ định những điều đó.

Trong các tình huống khi các phần của Tiêu chuẩn C hoặc C ++ và tài liệu triển khai cùng xác định hoặc mô tả một hành động, nhưng các phần khác mô tả nó là Không xác định, việc triển khai được phép xử lý mã theo bất kỳ cách nào phục vụ tốt nhất nhu cầu của khách hàng hoặc - nếu chúng thờ ơ với nhu cầu của khách hàng - bất cứ thời trang nào họ thấy phù hợp. Việc Tiêu chuẩn liên quan đến các vấn đề như bên ngoài phạm vi quyền hạn của họ không bao hàm bất kỳ phán xét nào về việc khi nào và / hoặc cách thức triển khai yêu cầu sự phù hợp cho các mục đích khác nhau nên được xử lý một cách có ý nghĩa, nhưng một số nhà bảo trì biên dịch đăng ký một huyền thoại mà nó thực hiện.


Đoạn đầu tiên: "Tất cả các cuộc gọi giữa mã C và C ++ đều gọi Hành vi không xác định" Ngay cả khi có một thứ gọi là "gọi hành vi không xác định" (không có), điều này vẫn vô nghĩa.
Các cuộc đua nhẹ nhàng trong quỹ đạo

Đoạn thứ hai: không biết bạn đang cố nói gì.
Các cuộc đua nhẹ nhàng trong quỹ đạo

@LightnessRacesinOrbit Tôi nghĩ rằng câu trả lời này là kết quả của việc tôi thêm thẻ [ngôn ngữ-luật sư] vào câu hỏi. Bây giờ tôi đã nghĩ tốt hơn về nó (các câu trả lời có xu hướng quá theo nghĩa đen) và loại bỏ nó.
SS Anne

1
@ JL2210 Tôi không nghĩ đó là lỗi của bạn.
Các cuộc đua nhẹ nhàng trong quỹ đạo
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.