Tôi có vấn đề tương tự khi sử dụng trình biên dịch lỗi thời (VisualDSP) trên nền tảng nhúng chưa hỗ trợ C++ 11 (và vì vậy tôi không thể sử dụng constexpr).
Tôi không cần phải đánh giá độ dài chuỗi trong trình biên dịch trước, nhưng tôi cần tối ưu hóa nó thành một nhiệm vụ duy nhất.
Chỉ trong trường hợp ai đó cần này trong tương lai, đây là giải pháp cực kỳ hacky của tôi mà phải làm việc trên các trình biên dịch thậm chí không hấp dẫn như miễn là họ làm tối ưu hóa thích hợp:
#define STRLENS(a,i) !a[i] ? i : // repetitive stuff
#define STRLENPADDED(a) (STRLENS(a,0) STRLENS(a,1) STRLENS(a,2) STRLENS(a,3) STRLENS(a,4) STRLENS(a,5) STRLENS(a,6) STRLENS(a,7) STRLENS(a,8) STRLENS(a,9) -1)
#define STRLEN(a) STRLENPADDED((a "\0\0\0\0\0\0\0\0\0")) // padding required to prevent 'index out of range' issues.
vĩ mô strlen này sẽ cung cấp cho bạn theo chiều dài của chuỗi ký tự mà bạn cung cấp, miễn là dài hơn 10 ký tự. Trong trường hợp của tôi điều này là đủ, nhưng trong trường hợp OPs macro có thể cần phải được mở rộng (rất nhiều). Vì nó là rất lặp đi lặp lại bạn có thể dễ dàng viết một kịch bản để tạo ra một vĩ mô chấp nhận 1000 ký tự.
PS: Đây chỉ là một nhánh đơn giản của vấn đề mà tôi đã thực sự cố gắng khắc phục, đây là một giá trị HASH được tính toán tĩnh cho một chuỗi nên tôi không cần sử dụng bất kỳ chuỗi nào trong hệ thống nhúng của mình. Trong trường hợp bất kỳ ai quan tâm (nó có thể đã cứu tôi một ngày tìm kiếm và giải quyết), điều này sẽ làm một mã hóa FNV trên một chuỗi nhỏ có thể được tối ưu hóa thành một nhiệm vụ duy nhất:
#ifdef _MSC_BUILD
#define HASH_FNV_OFFSET_BASIS 0x811c9dc5ULL
#define HASH_TYPE int
#else // properly define for your own compiler to get rid of overflow warnings
#define HASH_FNV_OFFSET_BASIS 0x811c9dc5UL
#define HASH_TYPE int
#endif
#define HASH_FNV_PRIME 16777619
#define HASH0(a) (a[0] ? ((HASH_TYPE)(HASH_FNV_OFFSET_BASIS * HASH_FNV_PRIME)^(HASH_TYPE)a[0]) : HASH_FNV_OFFSET_BASIS)
#define HASH2(a,i,b) ((b * (a[i] ? HASH_FNV_PRIME : 1))^(HASH_TYPE)(a[i] ? a[i] : 0))
#define HASHPADDED(a) HASH2(a,9,HASH2(a,8,HASH2(a,7,HASH2(a,6,HASH2(a,5,HASH2(a,4,HASH2(a,3,HASH2(a,2,HASH2(a,1,HASH0(a))))))))))
#define HASH(a) HASHPADDED((a "\0\0\0\0\0\0\0\0\0"))
Bạn có thể muốn chắc chắn rằng nó rõ ràng lý do tại sao nó đánh giá đến 5 và không 4. –
sizeof ("blah") là 5. Nhưng vấn đề là sizeof (blah) trong đó 'char * blah =" blah "' là 4 vì nó là một kích thước con trỏ trong hệ thống 32 bit. Đó là một vấn đề bởi vì chúng tôi không cần sizeof ("chuỗi cụ thể"). Chúng ta cần sizeof (given_pointer). Bạn sẽ phải sử dụng strlen (pointer) thay vào đó nhưng là sux và cần thêm +1 là một vấn đề nhỏ ở đây. – Val