2010-10-25 27 views
13

Tôi thỉnh thoảng sử dụng số học 64 bit trong thư viện C++ nguồn mở của tôi. Tôi phát hiện ra rằng long long phục vụ mục đích của tôi khá độc đáo. Ngay cả một số hộp solaris 10 năm tuổi cũng có thể biên dịch nó. Và nó hoạt động mà không rối tung xung quanh với #defines trên Windows.Cách thực hiện số học 64 bit di động, không có cảnh báo trình biên dịch

Bây giờ vấn đề là tôi nhận được khiếu nại từ người dùng vì họ biên dịch với cài đặt GCC -pantic, và GCC nhấn mạnh việc đưa ra cảnh báo rằng long long không thuộc tiêu chuẩn C++. Điều này có lẽ đúng, nhưng tôi không quá quan tâm đến tiêu chuẩn C++, tôi chỉ muốn mã của tôi làm việc trên nhiều trình biên dịch càng hợp lý càng tốt.

Vì vậy, câu hỏi của tôi có hai phần:

  • ai cũng có thể đặt tên cho trình biên dịch thực tế C++ không hỗ trợ 64 bit dài của lâu?
  • có cách nào để làm cho GCC biên dịch số học 64 bit (trên nền tảng 32 bit) mà không có cảnh báo trình biên dịch không? (stdint.h không hữu ích, vì nó cũng phụ thuộc vào long long)

P.S.

Nếu có nền tảng có thời lượng dài dài 128 bit trở lên, điều đó thật thú vị nhưng không phải là vấn đề đối với tôi.

+5

Sử dụng -pantic là một cách hay để có được * không * công việc được thực hiện và loại trừ việc sử dụng hầu hết các thư viện của bên thứ ba không có lý do chính đáng. Đó là những gì nó nói trên tin - một lời phàn nàn vô nghĩa, nhưng tôi không giả sử nói với người dùng của bạn ngừng việc ngớ ngẩn như vậy sẽ khiến bạn thích họ? – Clifford

+11

@Clifford: '-pedantic' là có để giúp bạn viết mã sẽ dễ dàng chuyển đến các trình biên dịch khác trong tương lai. Nếu bạn không lo lắng về điều đó, bạn không phải sử dụng nó, nhưng bạn sẽ kết thúc là người viết tất cả các thư viện của bên thứ ba đó (a) tạo ra những cảnh báo kỳ lạ, và (b) khá có thể không ' t làm việc trên một số trình biên dịch. Cấp, 'long long' không phải là vấn đề thực sự nhất, nhưng tôi từng làm việc trên một sản phẩm di động và nhiều lần chúng tôi sửa lỗi từ các chàng trai Windows thực sự không hoạt động trên một số nền tảng của chúng tôi (và gcc -pedantic đã nói với họ như vậy). –

+0

... lạ lùng, khi các lập trình viên Linux đang làm việc trên thành phần di động của sản phẩm, mã của họ ít có khả năng thất bại trong các thử nghiệm trên các nền tảng khác. –

Trả lời

15

Khi thư viện của bạn được cung cấp như nguồn, một lựa chọn là để cung cấp một "porting" tiêu đề, trong đó nó là của người dùng trách nhiệm cung cấp một loại 64 bit (bạn muốn xác định tên) . Nó cũng tự nhiên là trách nhiệm của họ để đối phó với bất kỳ cảnh báo trình biên dịch mà họ lựa chọn loại provokes, hoặc là tránh chúng, ngăn chặn chúng, hoặc bỏ qua chúng.

Tôi đoán đây là những gì bạn gọi là "lộn xộn với #defines", nhưng tôi không nghĩ có quá nhiều sai với nó. Bạn có thể cung cấp phiên bản mặc định chỉ sử dụng trực tiếp long long và sẽ hoạt động trên hộp Solaris 10 tuổi của bạn và cũng trên Windows, vì vậy hầu hết người dùng sẽ không bao giờ cần phải đi gần phần người dùng có thể định cấu hình của thư viện của bạn.

Sau đó đối với người dùng pedantic, bạn có thể cung cấp phiên bản cho GCC bao gồm <sys/types.h> và sử dụng int64_t thay vì long long. Điều này không kích động bất kỳ cảnh báo nào đối với tôi với g++ -pedantic.Bạn thậm chí có thể làm điều này trong phiên bản mặc định bằng cách nhận ra GCC, mà chắc chắn là rối tung xung quanh với #defines, nhưng một lần nữa không phải trong một cách đó là ở tất cả các bất thường cho một sản phẩm đa nền tảng.

Nếu thư viện của bạn cũng được cung cấp dưới dạng nhị phân cho một số nền tảng, thì tất nhiên bạn phải quyết định loại 64 bit sẽ là gì. Nếu nó cũng xuất hiện trong giao diện thư viện (và do đó các tập tin tiêu đề), sau đó bạn sẽ chỉ phải chọn một trong đó sẽ không kích động bất kỳ cảnh báo với các tùy chọn trình biên dịch hợp lý. Tôi nghĩ rằng -pedantic là một lựa chọn trình biên dịch hợp lý, và rõ ràng là để làm người dùng của bạn, vì vậy một lần nữa đó là int64_t trên GCC.

+0

+1, tôi nghĩ int64_t là giải pháp tốt nhất ở đây. – rmeador

+0

Tôi có một config.h.Tại một thời điểm nào đó, tôi đã sử dụng 'int64_t' (từ stdint.h), nhưng đã bỏ nó lâu dài vì nó được hỗ trợ rộng hơn rất nhiều. Điều thú vị là 'int64_t' (từ stdint.h) không hoạt động, mặc dù nó được gõ cho' long long' (trên hệ thống của tôi). Đánh tôi, nhưng cảm ơn vì đã đặt tôi đi đúng hướng. –

+0

@jdv: Đó là vì điều mà Void đề cập: tiêu đề của GCC sử dụng '__extension__', trong'/usr/include/sys/_types.h' trên máy của tôi. –

12

Trong GCC, hãy sử dụng tùy chọn biên dịch -Wno-long-long để chặn cảnh báo cụ thể đó.

Bạn cũng có thể sử dụng -std=C++0x, nhưng có thể sẽ làm giảm tính di động hơn nữa.

+0

Tôi thực sự hy vọng nó có thể được cố định mà không cần chuyển đổi dòng lệnh, nhưng cảm ơn, dù sao đi nữa. –

4

Bạn có thể tắt tiếng cảnh báo bằng -Wno-long-long (đảm bảo cảnh báo đến sau -pedantic). 64-bit số nguyên được yêu cầu của C99 và tôi nghĩ rằng cũng C + + 0x để trình biên dịch mà không có họ đang nhận được hiếm ngày nay.

+0

Tôi không nghĩ rằng hỗ trợ lâu dài 'là yêu cầu của C99, nhưng tôi nghĩ rằng đó là yêu cầu của C + + 0x. – Brian

+0

Tôi chắc chắn 100% là trong C99, nhưng tôi chắc chắn nó không có trong C++ 98. (Đó là một thỏa thuận lớn vào thời điểm đó, bởi vì Microsoft buộc ủy ban chấp nhận "sizeof (size_t)> sizeof (dài)' "như một tùy chọn ABI hợp pháp, mà C89 hứa sẽ không bao giờ xảy ra.) – zwol

+0

Tôi sẽ tiếp tục tranh luận về C99. –

0

Bạn có thể thay thế việc sử dụng long long bằng một trong nhiều thư viện C++ bigint. Tôi chắc chắn một số người trong số họ tránh lỗi trình biên dịch này. Cá nhân, tôi muốn gắn bó với lỗi.

4

Bạn cũng có thể ngăn chặn các cảnh báo sử dụng "__extension__" tính năng gcc của, ví dụ:

// No '-pedantic' warning/error. 
__extension__ long long foo = 2; 

// Exhibits '-pedantic' warning/error. 
long long bar = 3 

và biên dịch:

$ g++ -pedantic -fsyntax-only foo.cpp 
foo.cpp:5: error: ISO C++ 1998 does not support 'long long' 

Chú ý rằng chỉ việc sử dụng cuối cùng của long long kích hoạt lỗi -pedantic từ không có __extension__ được thêm vào trước. Bất kể, tôi muốn sử dụng số @Steve Jessop's suggestion thay vì sử dụng int64_t.

1

Nếu bạn có Boost trong một hệ thống bao gồm danh bạ, bạn có thể nói

#include "boost/cstdint.hpp" 
boost::int64_t my_64_bit_number; 

Nếu đó là trong một hệ thống bao gồm danh bạ, cảnh báo sẽ tự động bị ức chế.

+1

Tôi sẽ không sử dụng đề xuất này vì tôi chưa sử dụng tăng cường. Nhưng cảm ơn. –

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