aboutsummaryrefslogtreecommitdiffstats
path: root/OpenAL32/Include/alMain.h
diff options
context:
space:
mode:
authorChris Robinson <[email protected]>2016-10-04 16:25:43 -0700
committerChris Robinson <[email protected]>2016-10-04 16:25:43 -0700
commit9349ee9002c5cf2cd7906c9444292285529a91e9 (patch)
treee1574d31cc21e467162d234d8d66311d9d93c54d /OpenAL32/Include/alMain.h
parenta0e4696f5578fa42ec0ac7ac47141bf41fb727ff (diff)
Make some pointer-to-array parameters const
Diffstat (limited to 'OpenAL32/Include/alMain.h')
-rw-r--r--OpenAL32/Include/alMain.h42
1 files changed, 42 insertions, 0 deletions
diff --git a/OpenAL32/Include/alMain.h b/OpenAL32/Include/alMain.h
index af599227..837e1082 100644
--- a/OpenAL32/Include/alMain.h
+++ b/OpenAL32/Include/alMain.h
@@ -128,6 +128,48 @@ AL_API ALboolean AL_APIENTRY alIsBufferFormatSupportedSOFT(ALenum format);
#endif
+#ifdef __GNUC__
+/* Because of a long-standing deficiency in C, you're not allowed to implicitly
+ * cast a pointer-to-type-array to a pointer-to-const-type-array. For example,
+ *
+ * int (*ptr)[10];
+ * const int (*cptr)[10] = ptr;
+ *
+ * is not allowed and most compilers will generate noisy warnings about
+ * incompatible types, even though it just makes the array elements const.
+ * Clang will allow it if you make the array type a typedef, like this:
+ *
+ * typedef int int10[10];
+ * int10 *ptr;
+ * const int10 *cptr = ptr;
+ *
+ * however GCC does not and still issues the incompatible type warning. The
+ * "proper" way to fix it is to add an explicit cast for the constified type,
+ * but that removes the vast majority of otherwise useful type-checking you'd
+ * get, and runs the risk of improper casts if types are later changed. Leaving
+ * it non-const can also be an issue if you use it as a function parameter, and
+ * happen to have a const type as input (and also reduce the capabilities of
+ * the compiler to better optimize the function).
+ *
+ * So to work around the problem, we use a macro. The macro first assigns the
+ * incoming variable to the specified non-const type to ensure it's the correct
+ * type, then casts the variable as the desired constified type. Very ugly, but
+ * I'd rather not have hundreds of lines of warnings because I want to tell the
+ * compiler that some array(s) can't be changed by the code, or have lots of
+ * error-prone casts.
+ */
+#define SAFE_CONST(T, var) __extension__({ \
+ T _tmp = (var); \
+ (const T)_tmp; \
+})
+#else
+/* Non-GNU-compatible compilers have to use a straight cast with no extra
+ * checks, due to the lack of multi-statement expressions.
+ */
+#define SAFE_CONST(T, var) ((const T)(var))
+#endif
+
+
typedef ALint64SOFT ALint64;
typedef ALuint64SOFT ALuint64;