2010-09-30 35 views
8
// sizeofarray.cpp 
#include <iostream> 
template <typename T,int N> 
int size(T (&Array)[N]) 
{ 
    return N; 
} 

int main() 
{ 
    char p[]="Je suis trop bon, et vous?"; 
    char q[size(p)]; // (A) 
    return 0; 
} 

Tôi nghe nói rằng kích thước mảng trong C++ phải là biểu thức không đổi. Vì vậy, char q[size(p)] không hợp lệ, tôi có đúng không? Nhưng tôi không gặp lỗi khi tôi thửSử dụng kích thước của một mảng trong một mảng khác

g++ -Wall sizeofarray.cpp 

Tại sao?

+2

'q [sizeof (p)]' là tốt, có thể bạn có nghĩa là 'q [size (p)]'. Lưu ý rằng sau này sẽ trở thành hợp lệ trong C++ 0x (nếu bạn khai báo 'size' là' constexpr'). – avakar

+0

Vấn đề là với 'kích thước' thay vì sizeof. Xem bài đăng của tôi. – Chubsdad

+1

Hãy thử các tùy chọn trình biên dịch -pedantic hoặc -std = C++ 98 ;-) – sellibitze

Trả lời

4

Tôi nghe nói rằng kích thước mảng trong C++ phải là biểu thức không đổi.

Đúng

Vì vậy char q [size (p)] là không hợp lệ, tôi phải không?

Theo ISO C++, có!

Nhưng tôi đã không có lỗi khi tôi đã cố gắng

g ++ Wall sizeofarray.cpp

Đó là bởi vì g ++ hỗ trợ VLA (Variable Length Array) như một phần mở rộng.

Trong C++0xconstexpr tính năng với sự giúp đỡ trong đó bạn có thể viết

constexpr int size(T (&Array)[N]) 
{ 
    return N; 
} 

và sau đó char q[size(p)] sẽ là hợp pháp.

EDIT: Cũng đọc this bài viết [blog của bất cứ điều gì]

+1

chắc chắn sizeof là một biểu thức liên tục (ít nhất là cho một không vla mà tiêu chuẩn C + + thậm chí không có)? – nos

+0

@nos: yes :) .. –

+1

+1. Trong ví dụ cuối, 'sizeof' phải là' size'. – sellibitze

7

Giống như Prasoon says, nó không phải là một biểu hiện thường xuyên. Còn bây giờ, bạn có thể nhận được một giá trị không đổi thể hiện kích thước của một mảng như thế này:

template <std::size_t N> 
struct type_of_size 
{ 
    typedef char type[N]; 
}; 

template <typename T, std::size_t Size> 
typename type_of_size<Size>::type& sizeof_array_helper(T(&)[Size]); 

#define sizeof_array(pArray) sizeof(sizeof_array_helper(pArray)) 

Giải thích here. Về cơ bản bạn mã hóa kích thước của mảng vào kích thước của một loại, sau đó nhận được sizeof của loại hình đó, đem lại cho bạn:

char q[sizeof_array(p)]; 
+0

Dễ thương hack ':)', +1. –

-1

Tôi cầu xin khác biệt với tất cả các câu trả lời ở đây. Mã chương trình là hoàn toàn tốt đẹp ngoại trừ một vấn đề nhỏ (mà chắc chắn là không VLA)

template <typename T,int N> 
int size(T (&Array)[N]) 
{ 
    return N; 
} 

int main() 
{ 
    char p[]="Je suis trop bon, et vous?"; 
    char q[sizeof(p)]; // (A), not sizeof and not size as in OP 
    return 0; 
} 

tôi đã tự hỏi rằng kết quả của sizeof luôn là một giá trị const, và do đó các mã nên được tốt.

Đoạn mã trên được xây dựng tốt trên VS 2010 và Comeau (chế độ nghiêm ngặt)

$ 5.3.3/6- "Kết quả là một hằng số của kiểu size_t [Ghi chú:. Size_t được định nghĩa trong tiêu đề chuẩn (18.1). "

+2

Tôi nghĩ anh ấy có thể có nghĩa là 'char q [size (p)]'. Tôi đã thực hiện các chỉnh sửa cần thiết trong OP. –

-1

Tôi sử dụng g ++ 4.4.3 và có bí danh sau vì vậy mà tôi không bao giờ quên bật những lời cảnh báo:

$ alias g++ 
alias g++='g++ -ansi -pedantic -Wall -W -Wconversion -Wshadow -Wcast-qual -Wwrite-strings' 

Nếu biên soạn với ở trên, sẽ có một số cảnh báo. Các bước sau đây cho thấy các tùy chọn khác nhau hiển thị các cảnh báo khác nhau như thế nào.

Compilation không có tùy chọn cảnh báo không hiển thị bất kỳ cảnh báo

$ \g++ sizeofarray.cpp 

Bật -Wall

$ \g++ -Wall sizeofarray.cpp 
sizeofarray.cpp: In function ‘int main()’: 
sizeofarray.cpp:12: warning: unused variable ‘q’ 

Bật -Wextra

$ \g++ -Wall -Wextra sizeofarray.cpp 
sizeofarray.cpp: In function ‘int main()’: 
sizeofarray.cpp:12: warning: unused variable ‘q’ 
sizeofarray.cpp: At global scope: 
sizeofarray.cpp: In instantiation of ‘int size(T (&)[N]) [with T = char, int N = 27]’: 
sizeofarray.cpp:12: instantiated from here 
sizeofarray.cpp:4: warning: unused parameter ‘Array’ 

Cuối cùng bật -pedantic để bắt vấn đề thực sự

$ \g++ -Wall -Wextra -pedantic sizeofarray.cpp 
sizeofarray.cpp: In function ‘int main()’: 
sizeofarray.cpp:12: warning: ISO C++ forbids variable length array ‘q’ 
sizeofarray.cpp:12: warning: unused variable ‘q’ 
sizeofarray.cpp: At global scope: 
sizeofarray.cpp: In instantiation of ‘int size(T (&)[N]) [with T = char, int N = 27]’: 
sizeofarray.cpp:12: instantiated from here 
sizeofarray.cpp:4: warning: unused parameter ‘Array’ 
Các vấn đề liên quan