2015-07-28 50 views
29

Tôi thấy điều này here và tôi không biết những gì nó có nghĩa là:& (int) {1} có nghĩa là gì trong C++?

&(int) { 1 } 

Tôi nghĩ đó là lạ vì nó có vẻ như cú pháp hợp lệ. Nó đúc một phạm vi khối (?) Với một ngẫu nhiên 1 ở giữa (không có dấu chấm phẩy) và lấy địa chỉ. Không có nhiều ý nghĩa với tôi. Các bạn có thể khai sáng cho tôi không?

thử nó ra w/C++ 11, vì vậy nó biên dịch:

auto a = &(int) { 1 }; 

Nhưng tôi không có ý tưởng gì để làm với các biến.

+0

Bất kỳ ngữ cảnh nào từ đó đến từ đâu? Nó không tự [biên dịch] (http://ideone.com/hyQcy9) ... – yizzlez

+0

Trông giống như một [hợp chất theo nghĩa đen] (http://stackoverflow.com/q/28116467/1708801) nhưng không chắc chắn nếu không có nhiều ngữ cảnh hơn, nhiều khả năng đó là mã C vì nó được hỗ trợ như một phần mở rộng trong C++ và lấy địa chỉ của nó có lẽ sẽ là một ý tưởng tồi vì ngữ nghĩa là khác nhau. –

+0

@awesomeyi Tôi không nhớ. Và nó phổ biến cho mã tìm thấy trên google không biên dịch anyways –

Trả lời

32

Theo như tôi có thể nói đây là một compound literal, đó là tính năng C99, nó là not standard C++ nhưng cả hai gcc và kêu vang hỗ trợ nó như là một phần mở rộng:

ISO C99 hỗ trợ literals hợp chất. Một hợp chất theo nghĩa đen giống như một diễn viên có chứa một bộ khởi tạo. Giá trị của nó là một đối tượng của kiểu được chỉ định trong dàn diễn viên, chứa các phần tử được chỉ định trong bộ khởi tạo; nó là một lvalue. Là một phần mở rộng, GCC hỗ trợ các ký tự hợp chất trong chế độ C90 và trong C++, mặc dù ngữ nghĩa có phần khác nhau trong C++.

Thông thường, loại được chỉ định là cấu trúc. Giả sử rằng foo struct và cấu trúc được khai báo như hình:

struct foo {int a; char b[2];} structure; 

Dưới đây là một ví dụ về việc xây dựng một foo struct với một hợp chất đen:

structure = ((struct foo) {x + y, 'a', 0}); 

này tương đương với văn bản như sau:

{ 
    struct foo temp = {x + y, 'a', 0}; 
    struct 

Trong trường hợp này loại a sẽ con trỏ đến int. Hy vọng rằng đây là mã C ban đầu vì tài liệu gcc cho biết:

Trong C, một ký tự chữ chỉ định một đối tượng chưa đặt tên với thời gian lưu trữ tĩnh hoặc tự động. Trong C++, một hợp chất theo nghĩa đen chỉ định một đối tượng tạm thời, chỉ tồn tại cho đến khi kết thúc biểu thức đầy đủ của nó.

và do đó lấy địa chỉ trong C++ có lẽ là một ý tưởng tồi vì thời gian tồn tại của đối tượng kết thúc ở cuối biểu thức đầy đủ. Mặc dù, nó có thể là mã C++ mà chỉ dựa vào hành vi không xác định.

Đây là một trong những trường hợp sử dụng cờ đúng thực sự giúp ích rất nhiều, trong cả hai gcc và kêu vang bằng -pedantic sẽ tạo ra một cảnh báo và lỗi, ví dụ như gcc nói:

warning: ISO C++ forbids compound-literals [-Wpedantic] 
auto a = &(int) { 1 }; 
        ^
error: taking address of temporary [-fpermissive] 

nếu chúng tôi sử dụng -fpermissive là gcc, nó thực sự cho phép mã này biên dịch. Tôi không thể có được tiếng kêu để xây dựng mã này với bất kỳ cờ trong phiên bản hiện đại mặc dù phiên bản cũ dường như cho phép nó bằng cách sử dụng -Wno-address-of-temporary. Tôi tự hỏi, nếu gcc cho phép điều này như là một remnant of an old extension.

Lưu ý, câu hỏi Cryptic struct definition in C có một điều khá thú vị (tùy thuộc vào định nghĩa thú vị của bạn) sử dụng các ký tự hợp chất.

Giả ly giáo is correctthis question là nguồn gốc thì việc sử dụng trong mã mà trong ví dụ:

if (setsockopt(server_connection.socket, SOL_SOCKET, SO_REUSEADDR, &(int) { 1 }, sizeof(int)) < 0) { 

là một sử dụng hợp lệ trong cả C99 và C++.

5

Nó không rõ ràng ngay lập tức, nhưng nếu bạn nhìn vào mã xung quanh, nó trở nên rõ ràng những gì nó được sử dụng cho, và những gì nó có được.

Nó lấy địa chỉ của cấu trúc ẩn danh tạm thời chứa một số nguyên ẩn danh duy nhất được khởi tạo qua bộ khởi tạo được chỉ định C99. Lý do là setsockopt không muốn một số nguyên, nhưng là con trỏ đến số nguyên (hoặc đúng hơn là, con trỏ đến một cái gì đó và kích thước của một cái gì đó).

Nói cách khác, đó là rất mát hack để cung cấp một loại đối số nguyên (không có biến tạm thời rõ ràng) cho hàm có thể mong đợi một con trỏ.

Vì vậy, đó là chức năng giống với:

int blah = 1; 
setsockopt(..., &blah, ...); 

... ngoại trừ nó hoạt động mà không giới thiệu blah.

+0

Tôi có một chút cảnh giác với giả định rằng tham chiếu đó giống như một OP được đề cập đến ... Schism ngụ ý trong một nhận xét là nó đến từ đâu nhưng OP chưa xác nhận điều đó. Liên kết đã được thêm bởi người dùng khác chứ không phải OP. –

+0

@ShafikYaghmour: Ah, tôi không nhận thấy nhận xét đó không phải từ OP, nghĩ vậy. – Damon

Các vấn đề liên quan