https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63810
--- Comment #1 from Jeremy Huddleston Sequoia <jeremyhu at macports dot org> --- Larry said that he's working on a patch to fix this for gcc trunk, and I suspect he's pretty close to having something since that was about a week ago. The algorithm for determining what the macro should be is quite simple: Split the string by "." Use implicit "0" if there are less than three elements. if (first field is >10) or (first field is 10 and second field >= 10), use "%02d%02d%02d" as the format else use "%02d%01d%01d" as the format I had to do this in bash for some unrelated reason, and here it is in case it is helpful to you: BUILD_MAJOR=$(echo ${PRODUCT_VERSION} | cut -f1 -d.) BUILD_MINOR=$(echo ${PRODUCT_VERSION} | cut -f2 -d.) BUILD_TINY=$(echo ${PRODUCT_VERSION} | cut -f3 -d.) [[ -z "${BUILD_MINOR}" ]] && BUILD_MINOR="0" [[ -z "${BUILD_TINY}" ]] && BUILD_TINY="0" if ((BUILD_MAJOR > 10 || (BUILD_MAJOR == 10 && BUILD_MINOR >= 10))) ; then VERSION_ENCODED=$(printf "%02d%02d%02d" ${BUILD_MAJOR} ${BUILD_MINOR} ${BUILD_TINY}) else VERSION_ENCODED=$(printf "%02d%01d%01d" ${BUILD_MAJOR} ${BUILD_MINOR} ${BUILD_TINY}) fi For clang, I did this (slightly less clean): - char Str[5]; - Str[0] = '0' + (Maj / 10); - Str[1] = '0' + (Maj % 10); - Str[2] = '0' + std::min(Min, 9U); - Str[3] = '0' + std::min(Rev, 9U); - Str[4] = '\0'; + char Str[7]; + if (Maj < 10 || Maj == 10 && Min < 10) { + Str[0] = '0' + (Maj / 10); + Str[1] = '0' + (Maj % 10); + Str[2] = '0' + std::min(Min, 9U); + Str[3] = '0' + std::min(Rev, 9U); + Str[4] = '\0'; + } else { + Str[0] = '0' + (Maj / 10); + Str[1] = '0' + (Maj % 10); + Str[2] = '0' + (Min / 10); + Str[3] = '0' + (Min % 10); + Str[4] = '0' + (Rev / 10); + Str[5] = '0' + (Rev % 10); + Str[6] = '\0'; + }