diff --git a/CMakeLists.txt b/CMakeLists.txt
index b8e4d6d402ab0d28f2b487b6e6d582a662f98c90..aa0233027e85d2f9a683fb3330d008645070715a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -478,19 +478,54 @@ IF(UNIX)
 ENDIF(UNIX)
 
 IF(KWSYS_USE_FundamentalType)
-  # Determine type sizes.
-  CHECK_TYPE_SIZE("char"      KWSYS_SIZEOF_CHAR)
-  CHECK_TYPE_SIZE("short"     KWSYS_SIZEOF_SHORT)
-  CHECK_TYPE_SIZE("int"       KWSYS_SIZEOF_INT)
-  CHECK_TYPE_SIZE("long"      KWSYS_SIZEOF_LONG)
-  CHECK_TYPE_SIZE("long long" KWSYS_SIZEOF_LONG_LONG)
-  CHECK_TYPE_SIZE("__int64"   KWSYS_SIZEOF___INT64)
-  IF(NOT KWSYS_SIZEOF_LONG_LONG)
-    SET(KWSYS_SIZEOF_LONG_LONG 0)
-  ENDIF(NOT KWSYS_SIZEOF_LONG_LONG)
-  IF(NOT KWSYS_SIZEOF___INT64)
-    SET(KWSYS_SIZEOF___INT64 0)
-  ENDIF(NOT KWSYS_SIZEOF___INT64)
+  # Look for type size helper macros.
+  KWSYS_PLATFORM_INFO_TEST(C KWSYS_C_TYPE_MACROS
+    "Checking for C type size macros")
+  SET(macro_regex ".*INFO:macro\\[([^]]*)\\].*")
+  FOREACH(info ${KWSYS_C_TYPE_MACROS})
+    IF("${info}" MATCHES "${macro_regex}")
+      STRING(REGEX REPLACE "${macro_regex}" "\\1" macro "${info}")
+      SET(KWSYS_C_HAS_MACRO_${macro} 1)
+    ENDIF()
+  ENDFOREACH()
+
+  # Determine type sizes at preprocessing time if possible, and
+  # otherwise fall back to a try-compile.
+  SET(KWSYS_C_TYPE_NAME_CHAR      "char")
+  SET(KWSYS_C_TYPE_NAME_SHORT     "short")
+  SET(KWSYS_C_TYPE_NAME_INT       "int")
+  SET(KWSYS_C_TYPE_NAME_LONG      "long")
+  SET(KWSYS_C_TYPE_NAME_LONG_LONG "long long")
+  SET(KWSYS_C_TYPE_NAME___INT64   "__int64")
+  FOREACH(type CHAR SHORT INT LONG LONG_LONG __INT64)
+    IF(KWSYS_C_HAS_MACRO___SIZEOF_${type}__)
+      # Use __SIZEOF_${type}__ macro.
+      SET(KWSYS_SIZEOF_${type} TRUE)
+      SET(KWSYS_C_CODE_SIZEOF_${type} "#define ${KWSYS_NAMESPACE}_SIZEOF_${type} __SIZEOF_${type}__")
+    ELSEIF(KWSYS_C_HAS_MACRO___${type}_MAX__)
+      # Use __${type}_MAX__ macro.
+      SET(KWSYS_SIZEOF_${type} TRUE)
+      SET(KWSYS_C_CODE_SIZEOF_${type} "#if __${type}_MAX__ == 0x7f
+# define ${KWSYS_NAMESPACE}_SIZEOF_${type} 1
+#elif __${type}_MAX__ == 0x7fff
+# define ${KWSYS_NAMESPACE}_SIZEOF_${type} 2
+#elif __${type}_MAX__ == 0x7fffffff
+# define ${KWSYS_NAMESPACE}_SIZEOF_${type} 4
+#elif __${type}_MAX__>>32 == 0x7fffffff
+# define ${KWSYS_NAMESPACE}_SIZEOF_${type} 8
+#else
+# error \"Cannot determine sizeof(${KWSYS_C_TYPE_NAME_${type}}).\"
+#endif")
+    ELSE()
+      # Configure a hard-coded type size.
+      CHECK_TYPE_SIZE("${KWSYS_C_TYPE_NAME_${type}}" KWSYS_SIZEOF_${type})
+      IF(NOT KWSYS_SIZEOF_${type})
+        SET(KWSYS_SIZEOF_${type} 0)
+      ENDIF()
+      SET(KWSYS_C_CODE_SIZEOF_${type}
+        "#define ${KWSYS_NAMESPACE}_SIZEOF_${type} ${KWSYS_SIZEOF_${type}}")
+    ENDIF()
+  ENDFOREACH()
 
   # Check uniqueness of types.
   IF(KWSYS_SIZEOF___INT64)
diff --git a/FundamentalType.h.in b/FundamentalType.h.in
index aabe822efb84611306e2fd04024a7c897c266ade..ff200633afcda92270b200344d87bb35b9baca21 100644
--- a/FundamentalType.h.in
+++ b/FundamentalType.h.in
@@ -36,12 +36,12 @@
 #endif
 
 /* The size of fundamental types.  Types that do not exist have size 0.  */
-#define @KWSYS_NAMESPACE@_SIZEOF_CHAR @KWSYS_SIZEOF_CHAR@
-#define @KWSYS_NAMESPACE@_SIZEOF_SHORT @KWSYS_SIZEOF_SHORT@
-#define @KWSYS_NAMESPACE@_SIZEOF_INT @KWSYS_SIZEOF_INT@
-#define @KWSYS_NAMESPACE@_SIZEOF_LONG @KWSYS_SIZEOF_LONG@
-#define @KWSYS_NAMESPACE@_SIZEOF_LONG_LONG @KWSYS_SIZEOF_LONG_LONG@
-#define @KWSYS_NAMESPACE@_SIZEOF___INT64 @KWSYS_SIZEOF___INT64@
+@KWSYS_C_CODE_SIZEOF_CHAR@
+@KWSYS_C_CODE_SIZEOF_SHORT@
+@KWSYS_C_CODE_SIZEOF_INT@
+@KWSYS_C_CODE_SIZEOF_LONG@
+@KWSYS_C_CODE_SIZEOF_LONG_LONG@
+@KWSYS_C_CODE_SIZEOF___INT64@
 
 /* Whether types "long long" and "__int64" are enabled.  If a type is
    enabled then it is a unique fundamental type.  */
diff --git a/kwsysPlatformTestsC.c b/kwsysPlatformTestsC.c
index 0d26347d15b7fcd37ead82779acc34280e2d41cb..e602964bb75ef161fd04312a2ec64373592fe6ce 100644
--- a/kwsysPlatformTestsC.c
+++ b/kwsysPlatformTestsC.c
@@ -60,3 +60,41 @@ int KWSYS_PLATFORM_TEST_C_MAIN()
   return f(n);
 }
 #endif
+
+/*--------------------------------------------------------------------------*/
+#ifdef TEST_KWSYS_C_TYPE_MACROS
+char* info_macros =
+#if defined(__SIZEOF_SHORT__)
+"INFO:macro[__SIZEOF_SHORT__]\n"
+#endif
+#if defined(__SIZEOF_INT__)
+"INFO:macro[__SIZEOF_INT__]\n"
+#endif
+#if defined(__SIZEOF_LONG__)
+"INFO:macro[__SIZEOF_LONG__]\n"
+#endif
+#if defined(__SIZEOF_LONG_LONG__)
+"INFO:macro[__SIZEOF_LONG_LONG__]\n"
+#endif
+#if defined(__SHORT_MAX__)
+"INFO:macro[__SHORT_MAX__]\n"
+#endif
+#if defined(__INT_MAX__)
+"INFO:macro[__INT_MAX__]\n"
+#endif
+#if defined(__LONG_MAX__)
+"INFO:macro[__LONG_MAX__]\n"
+#endif
+#if defined(__LONG_LONG_MAX__)
+"INFO:macro[__LONG_LONG_MAX__]\n"
+#endif
+  "";
+
+int KWSYS_PLATFORM_TEST_C_MAIN_ARGS(argc, argv)
+{
+  int require = 0;
+  require += info_macros[argc];
+  (void)argv;
+  return require;
+}
+#endif