From: Christopher Dykes Date: Thu, 18 Feb 2016 23:24:48 +0000 (-0800) Subject: Don't use a VLA for the double->string buffer. X-Git-Tag: deprecate-dynamic-initializer~60 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=ad925ffabc3a5d452927242efdff0ba70f34626d;p=folly.git Don't use a VLA for the double->string buffer. Summary: MSVC is actually smarter about this than GCC, as MSVC doesn't support VLAs, it tries to eval the length at compile time. GCC on the other hand doesn't try to eval it at compile time, resulting in compiles via CMake telling us that this is a VLA. Reviewed By: yfeldblum Differential Revision: D2911929 fb-gh-sync-id: ffaa133bcf4129a3e02f7e875966d3ae6a97be6a shipit-source-id: ffaa133bcf4129a3e02f7e875966d3ae6a97be6a --- diff --git a/folly/Format.cpp b/folly/Format.cpp index d3a433ab..0d1d61b1 100644 --- a/folly/Format.cpp +++ b/folly/Format.cpp @@ -16,6 +16,8 @@ #include +#include + #include namespace folly { @@ -48,11 +50,13 @@ void FormatValue::formatHelper( } // 2+: for null terminator and optional sign shenanigans. - char buf[2 + std::max( - 2 + DoubleToStringConverter::kMaxFixedDigitsBeforePoint + - DoubleToStringConverter::kMaxFixedDigitsAfterPoint, - std::max(8 + DoubleToStringConverter::kMaxExponentialDigits, - 7 + DoubleToStringConverter::kMaxPrecisionDigits))]; + constexpr size_t bufLen = + 2 + constexpr_max( + 2 + DoubleToStringConverter::kMaxFixedDigitsBeforePoint + + DoubleToStringConverter::kMaxFixedDigitsAfterPoint, + constexpr_max(8 + DoubleToStringConverter::kMaxExponentialDigits, + 7 + DoubleToStringConverter::kMaxPrecisionDigits)); + char buf[bufLen]; StringBuilder builder(buf + 1, static_cast (sizeof(buf) - 1)); char plusSign; diff --git a/folly/Makefile.am b/folly/Makefile.am index b4e5ecf7..ddef486a 100644 --- a/folly/Makefile.am +++ b/folly/Makefile.am @@ -263,6 +263,7 @@ nobase_follyinclude_HEADERS = \ Padded.h \ PicoSpinLock.h \ Portability.h \ + portability/Constexpr.h \ portability/Syscall.h \ portability/SysUio.h \ Preprocessor.h \ diff --git a/folly/Portability.h b/folly/Portability.h index b35bdee8..a6241fea 100644 --- a/folly/Portability.h +++ b/folly/Portability.h @@ -448,24 +448,6 @@ inline void asm_pause() { #endif } -#ifdef _MSC_VER -constexpr size_t constexpr_strlen_internal(const char* s, size_t len) { - return *s == '\0' ? len : constexpr_strlen_internal(s + 1, len + 1); -} -static_assert(constexpr_strlen_internal("123456789", 0) == 9, - "Someone appears to have broken constexpr_strlen..."); -#endif - -constexpr size_t constexpr_strlen(const char* s) { -#if defined(__clang__) - return __builtin_strlen(s); -#elif defined(_MSC_VER) - return s == nullptr ? 0 : constexpr_strlen_internal(s, 0); -#else - return strlen(s); -#endif -} - #if defined(__APPLE__) || defined(_MSC_VER) #define MAX_STATIC_CONSTRUCTOR_PRIORITY #else diff --git a/folly/Range.h b/folly/Range.h index 3080626a..d42fe548 100644 --- a/folly/Range.h +++ b/folly/Range.h @@ -23,6 +23,7 @@ #include #include #include +#include #include #include diff --git a/folly/json.cpp b/folly/json.cpp index 4d29a897..4fb7d04a 100644 --- a/folly/json.cpp +++ b/folly/json.cpp @@ -24,6 +24,7 @@ #include #include #include +#include namespace folly { diff --git a/folly/portability/Constexpr.h b/folly/portability/Constexpr.h new file mode 100755 index 00000000..810f987a --- /dev/null +++ b/folly/portability/Constexpr.h @@ -0,0 +1,53 @@ +/* + * Copyright 2016 Facebook, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FOLLY_CONSTEXPR_H_ +#define FOLLY_CONSTEXPR_H_ + +#include + +namespace folly { + +template +constexpr T constexpr_max(T a, T b) { + return a > b ? a : b; +} + +template +constexpr T constexpr_min(T a, T b) { + return a < b ? a : b; +} + +#ifdef _MSC_VER +constexpr size_t constexpr_strlen_internal(const char* s, size_t len) { + return *s == '\0' ? len : constexpr_strlen_internal(s + 1, len + 1); +} +static_assert(constexpr_strlen_internal("123456789", 0) == 9, + "Someone appears to have broken constexpr_strlen..."); +#endif + +constexpr size_t constexpr_strlen(const char* s) { +#if defined(__clang__) + return __builtin_strlen(s); +#elif defined(_MSC_VER) + return s == nullptr ? 0 : constexpr_strlen_internal(s, 0); +#else + return strlen(s); +#endif +} +} + +#endif