convert skcms to c++

The main thing we do here is add a 'c' to the skcms source path.

The rest is build system updates and little language tweaks.

I have had to explicitly set -ffp-contract=off in GCC.  Switching
from C11 to C++11 changed the default -ffp-contract from "off" to
"fast", which generates FMAs in places we don't want them.  This
behavior is rooted in this lovely piece of code:

  /* ISO C restricts floating-point expression contraction to within
     source-language expressions (-ffp-contract=on, currently an alias
     for -ffp-contract=off).  */
  if (flag_iso
      && !c_dialect_cxx ()
      && (global_options_set.x_flag_fp_contract_mode
          == (enum fp_contract_mode) 0)
      && flag_unsafe_math_optimizations == 0)
    flag_fp_contract_mode = FP_CONTRACT_OFF;

Change-Id: Ica2d83b8dadce72fffe298b517bd34cdc609f49e
Reviewed-on: https://skia-review.googlesource.com/139167
Commit-Queue: Brian Osman <brianosman@google.com>
Auto-Submit: Mike Klein <mtklein@chromium.org>
Reviewed-by: Brian Osman <brianosman@google.com>
diff --git a/build/android-arm-gcc b/build/android-arm-gcc
index 2dc13d2..1b1c452 100644
--- a/build/android-arm-gcc
+++ b/build/android-arm-gcc
@@ -5,7 +5,6 @@
 
 cc      = $ndk/toolchains/${target}-4.9/prebuilt/*/bin/${target}-gcc
 cflags  = -fdiagnostics-color -Wall -Wextra $
-          -std=c11 $
           -march=armv7-a -mfpu=neon -mthumb -mfloat-abi=softfp $
           --sysroot $ndk/sysroot $
           -I $ndk/sysroot/usr/include/$target
diff --git a/build/clang.xsan b/build/clang.xsan
index 014fec4..e28fb3a 100644
--- a/build/clang.xsan
+++ b/build/clang.xsan
@@ -1,4 +1,4 @@
 mode          = .xsan
 extra_cflags  = -fsanitize=address,integer,undefined -fno-sanitize-recover=all
-extra_ldflags = -fsanitize=address,integer,undefined
+extra_ldflags = -fsanitize=address,integer,undefined -lc++
 include build/clang
diff --git a/build/common b/build/common
index 8f28220..20baea5 100644
--- a/build/common
+++ b/build/common
@@ -10,8 +10,23 @@
            -Wno-padded $
            -Wno-reserved-id-macro $
 
-rule compile
-    command = $disabled && touch $out || $cc -g $warnings -Os $cflags $extra_cflags $
+warnings_cc = $warnings $
+           -Wno-c++98-compat-pedantic $
+           -Wno-c99-extensions $
+           -Wno-gnu-anonymous-struct $
+           -Wno-narrowing $
+           -Wno-old-style-cast $
+
+
+rule compile_c
+    command = $disabled && touch $out || $cc -std=c11 -g -Os $warnings $cflags $extra_cflags $
+             -MD -MF $out.d -c $in -o $out
+    depfile = $out.d
+    deps    = gcc
+    description = compile $out
+
+rule compile_cc
+    command = $disabled && touch $out || $cc -std=c++11 -g -Os $warnings_cc $cflags $extra_cflags $
              -MD -MF $out.d -c $in -o $out
     depfile = $out.d
     deps    = gcc
diff --git a/build/gcc b/build/gcc
index d60d469..2b6e1f9 100644
--- a/build/gcc
+++ b/build/gcc
@@ -1,5 +1,5 @@
 cc     = gcc
-cflags = -std=c11 -fdiagnostics-color -Wall -Wextra -fstack-usage
+cflags = -fdiagnostics-color -Wall -Wextra -ffp-contract=off -fstack-usage
 out    = out/gcc$mode
 
 include build/local
diff --git a/build/gcc.xsan b/build/gcc.xsan
index 150ce07..a53f6ec 100644
--- a/build/gcc.xsan
+++ b/build/gcc.xsan
@@ -1,4 +1,4 @@
 mode          = .xsan
 extra_cflags  = -fsanitize=address,undefined -fno-sanitize-recover=all
-extra_ldflags = -fsanitize=address,undefined
+extra_ldflags = -fsanitize=address,undefined -lstdc++
 include build/gcc
diff --git a/build/msvs b/build/msvs
index 2d87d37..1c2f64e 100644
--- a/build/msvs
+++ b/build/msvs
@@ -8,7 +8,13 @@
     command = cmd /c ""$in" > "$out""
     description = run $in
 
-rule compile
+rule compile_c
+    command = $cl /c /showIncludes /nologo /Zi /WX /MT /Fo"$out" /Fd"$out.pdb" $
+              $cflags $extra_cflags $in
+    deps = msvc
+    description = compile $out
+
+rule compile_cc
     command = $cl /c /showIncludes /nologo /Zi /WX /MT /Fo"$out" /Fd"$out.pdb" $
               $cflags $extra_cflags $in
     deps = msvc
diff --git a/build/targets b/build/targets
index 5e2c5f8..54ff8c9 100644
--- a/build/targets
+++ b/build/targets
@@ -1,30 +1,30 @@
-build $out/skcms.o: compile skcms.c
+build $out/skcms.o: compile_cc skcms.cc
 
-build $out/test_only.o: compile test_only.c
+build $out/test_only.o: compile_c test_only.c
 
-build $out/tests.o:   compile tests.c
+build $out/tests.o:   compile_c tests.c
 build $out/tests$exe: link $out/skcms.o $out/tests.o $out/test_only.o
 build $out/tests.ok:  run  $out/tests$exe
 
-build $out/bench.o:   compile bench.c
+build $out/bench.o:   compile_c bench.c
 build $out/bench$exe: link $out/skcms.o $out/bench.o
 
-build $out/iccdump.o:   compile iccdump.c
+build $out/iccdump.o:   compile_c iccdump.c
 build $out/iccdump$exe: link $out/skcms.o $out/iccdump.o $out/test_only.o
 
-build $out/fuzz/fuzz_main.o: compile fuzz/fuzz_main.c
+build $out/fuzz/fuzz_main.o: compile_c fuzz/fuzz_main.c
 
-build $out/fuzz/fuzz_iccprofile_atf.o: compile fuzz/fuzz_iccprofile_atf.c
-build $out/fuzz_iccprofile_atf$exe:  link $out/fuzz/fuzz_iccprofile_atf.o $
-                                          $out/fuzz/fuzz_main.o $
-                                          $out/skcms.o
+build $out/fuzz/fuzz_iccprofile_atf.o: compile_c fuzz/fuzz_iccprofile_atf.c
+build $out/fuzz_iccprofile_atf$exe:    link $out/fuzz/fuzz_iccprofile_atf.o $
+                                            $out/fuzz/fuzz_main.o $
+                                            $out/skcms.o
 
-build $out/fuzz/fuzz_iccprofile_info.o: compile fuzz/fuzz_iccprofile_info.c
-build $out/fuzz_iccprofile_info$exe:  link $out/fuzz/fuzz_iccprofile_info.o $
-                                           $out/fuzz/fuzz_main.o $
-                                           $out/skcms.o
+build $out/fuzz/fuzz_iccprofile_info.o: compile_c fuzz/fuzz_iccprofile_info.c
+build $out/fuzz_iccprofile_info$exe:    link $out/fuzz/fuzz_iccprofile_info.o $
+                                             $out/fuzz/fuzz_main.o $
+                                             $out/skcms.o
 
-build $out/fuzz/fuzz_iccprofile_transform.o: compile fuzz/fuzz_iccprofile_transform.c
-build $out/fuzz_iccprofile_transform$exe:  link $out/fuzz/fuzz_iccprofile_transform.o $
-                                                $out/fuzz/fuzz_main.o $
-                                                $out/skcms.o
+build $out/fuzz/fuzz_iccprofile_transform.o: compile_c fuzz/fuzz_iccprofile_transform.c
+build $out/fuzz_iccprofile_transform$exe:    link $out/fuzz/fuzz_iccprofile_transform.o $
+                                                  $out/fuzz/fuzz_main.o $
+                                                  $out/skcms.o
diff --git a/skcms.c b/skcms.cc
similarity index 96%
rename from skcms.c
rename to skcms.cc
index 99b05cb..9c62fe4 100644
--- a/skcms.c
+++ b/skcms.cc
@@ -364,7 +364,7 @@
             curve->parametric.g = read_big_u16(curvTag->parameters) * (1.0f / 256.0f);
         }
     } else {
-        curve->table_8       = NULL;
+        curve->table_8       = nullptr;
         curve->table_16      = curvTag->parameters;
         curve->table_entries = value_count;
     }
@@ -373,7 +373,7 @@
 }
 
 // Parses both curveType and parametricCurveType data. Ensures that at most 'size' bytes are read.
-// If curve_size is not NULL, writes the number of bytes used by the curve in (*curve_size).
+// If curve_size is not nullptr, writes the number of bytes used by the curve in (*curve_size).
 static bool read_curve(const uint8_t* buf, uint32_t size,
                        skcms_Curve* curve, uint32_t* curve_size) {
     if (!buf || size < 4 || !curve) {
@@ -469,18 +469,18 @@
         a2b->input_curves[i].table_entries = input_table_entries;
         if (byte_width == 1) {
             a2b->input_curves[i].table_8  = table_base + i * byte_len_per_input_table;
-            a2b->input_curves[i].table_16 = NULL;
+            a2b->input_curves[i].table_16 = nullptr;
         } else {
-            a2b->input_curves[i].table_8  = NULL;
+            a2b->input_curves[i].table_8  = nullptr;
             a2b->input_curves[i].table_16 = table_base + i * byte_len_per_input_table;
         }
     }
 
     if (byte_width == 1) {
         a2b->grid_8  = table_base + byte_len_all_input_tables;
-        a2b->grid_16 = NULL;
+        a2b->grid_16 = nullptr;
     } else {
-        a2b->grid_8  = NULL;
+        a2b->grid_8  = nullptr;
         a2b->grid_16 = table_base + byte_len_all_input_tables;
     }
 
@@ -489,9 +489,9 @@
         a2b->output_curves[i].table_entries = output_table_entries;
         if (byte_width == 1) {
             a2b->output_curves[i].table_8  = output_table_base + i * byte_len_per_output_table;
-            a2b->output_curves[i].table_16 = NULL;
+            a2b->output_curves[i].table_16 = nullptr;
         } else {
-            a2b->output_curves[i].table_8  = NULL;
+            a2b->output_curves[i].table_8  = nullptr;
             a2b->output_curves[i].table_16 = output_table_base + i * byte_len_per_output_table;
         }
     }
@@ -674,9 +674,9 @@
 
         if (clut->grid_byte_width[0] == 1) {
             a2b->grid_8  = clut->data;
-            a2b->grid_16 = NULL;
+            a2b->grid_16 = nullptr;
         } else if (clut->grid_byte_width[0] == 2) {
-            a2b->grid_8  = NULL;
+            a2b->grid_8  = nullptr;
             a2b->grid_16 = clut->data;
         } else {
             return false;
@@ -770,16 +770,16 @@
 
     // Detect and canonicalize identity tables.
     skcms_Curve* curves[] = {
-        a2b->input_channels  > 0 ? a2b->input_curves  + 0 : NULL,
-        a2b->input_channels  > 1 ? a2b->input_curves  + 1 : NULL,
-        a2b->input_channels  > 2 ? a2b->input_curves  + 2 : NULL,
-        a2b->input_channels  > 3 ? a2b->input_curves  + 3 : NULL,
-        a2b->matrix_channels > 0 ? a2b->matrix_curves + 0 : NULL,
-        a2b->matrix_channels > 1 ? a2b->matrix_curves + 1 : NULL,
-        a2b->matrix_channels > 2 ? a2b->matrix_curves + 2 : NULL,
-        a2b->output_channels > 0 ? a2b->output_curves + 0 : NULL,
-        a2b->output_channels > 1 ? a2b->output_curves + 1 : NULL,
-        a2b->output_channels > 2 ? a2b->output_curves + 2 : NULL,
+        a2b->input_channels  > 0 ? a2b->input_curves  + 0 : nullptr,
+        a2b->input_channels  > 1 ? a2b->input_curves  + 1 : nullptr,
+        a2b->input_channels  > 2 ? a2b->input_curves  + 2 : nullptr,
+        a2b->input_channels  > 3 ? a2b->input_curves  + 3 : nullptr,
+        a2b->matrix_channels > 0 ? a2b->matrix_curves + 0 : nullptr,
+        a2b->matrix_channels > 1 ? a2b->matrix_curves + 1 : nullptr,
+        a2b->matrix_channels > 2 ? a2b->matrix_curves + 2 : nullptr,
+        a2b->output_channels > 0 ? a2b->output_curves + 0 : nullptr,
+        a2b->output_channels > 1 ? a2b->output_curves + 1 : nullptr,
+        a2b->output_channels > 2 ? a2b->output_curves + 2 : nullptr,
     };
 
     for (int i = 0; i < ARRAY_COUNT(curves); i++) {
@@ -793,9 +793,9 @@
                 && c == 1.0f
                 && f == 0.0f) {
                 curve->table_entries = 0;
-                curve->table_8       = NULL;
-                curve->table_16      = NULL;
-                curve->parametric    = (skcms_TransferFunction){1,1,0,0,0,0,0};
+                curve->table_8       = nullptr;
+                curve->table_16      = nullptr;
+                curve->parametric    = skcms_TransferFunction{1,1,0,0,0,0,0};
             }
         }
     }
@@ -896,7 +896,7 @@
     skcms_ICCTag kTRC;
     if (profile->data_color_space == skcms_Signature_Gray &&
         skcms_GetTagBySignature(profile, skcms_Signature_kTRC, &kTRC)) {
-        if (!read_curve(kTRC.buf, kTRC.size, &profile->trc[0], NULL)) {
+        if (!read_curve(kTRC.buf, kTRC.size, &profile->trc[0], nullptr)) {
             // Malformed tag
             return false;
         }
@@ -915,9 +915,9 @@
         if (skcms_GetTagBySignature(profile, skcms_Signature_rTRC, &rTRC) &&
             skcms_GetTagBySignature(profile, skcms_Signature_gTRC, &gTRC) &&
             skcms_GetTagBySignature(profile, skcms_Signature_bTRC, &bTRC)) {
-            if (!read_curve(rTRC.buf, rTRC.size, &profile->trc[0], NULL) ||
-                !read_curve(gTRC.buf, gTRC.size, &profile->trc[1], NULL) ||
-                !read_curve(bTRC.buf, bTRC.size, &profile->trc[2], NULL)) {
+            if (!read_curve(rTRC.buf, rTRC.size, &profile->trc[0], nullptr) ||
+                !read_curve(gTRC.buf, gTRC.size, &profile->trc[1], nullptr) ||
+                !read_curve(bTRC.buf, bTRC.size, &profile->trc[2], nullptr)) {
                 // Malformed TRC tags
                 return false;
             }
@@ -960,7 +960,7 @@
 
 const skcms_ICCProfile* skcms_sRGB_profile() {
     static const skcms_ICCProfile sRGB_profile = {
-        NULL,                  // buffer, moot here
+        nullptr,               // buffer, moot here
 
         0,                     // size, moot here
         skcms_Signature_RGB,   // data_color_space
@@ -993,8 +993,8 @@
                 {{0, {1,1, 0,0,0,0,0}}},
             },
             {0,0,0,0},
-            NULL,
-            NULL,
+            nullptr,
+            nullptr,
 
             0,
             {
@@ -1022,7 +1022,7 @@
 const skcms_ICCProfile* skcms_XYZD50_profile() {
     // Just like sRGB above, but with identity transfer functions and toXYZD50 matrix.
     static const skcms_ICCProfile XYZD50_profile = {
-        NULL,                  // buffer, moot here
+        nullptr,               // buffer, moot here
 
         0,                     // size, moot here
         skcms_Signature_RGB,   // data_color_space
@@ -1053,8 +1053,8 @@
                 {{0, {1,1, 0,0,0,0,0}}},
             },
             {0,0,0,0},
-            NULL,
-            NULL,
+            nullptr,
+            nullptr,
 
             0,
             {
@@ -1871,8 +1871,8 @@
     #define U16 U16x16
     #define U8   U8x16
 
-    #define F0 (F){0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0}
-    #define F1 (F){1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1}
+    #define F0 F{0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0}
+    #define F1 F{1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1}
 #elif defined(__AVX__)
     #define N 8
 
@@ -1883,8 +1883,8 @@
     #define U16 U16x8
     #define U8   U8x8
 
-    #define F0 (F){0,0,0,0, 0,0,0,0}
-    #define F1 (F){1,1,1,1, 1,1,1,1}
+    #define F0 F{0,0,0,0, 0,0,0,0}
+    #define F1 F{1,1,1,1, 1,1,1,1}
 #else
     #define N 4
 
@@ -1895,8 +1895,8 @@
     #define U16 U16x4
     #define U8   U8x4
 
-    #define F0 (F){0,0,0,0}
-    #define F1 (F){1,1,1,1}
+    #define F0 F{0,0,0,0}
+    #define F1 F{1,1,1,1}
 #endif
 
 #define NS(id) id
@@ -1924,8 +1924,8 @@
     #define I32 I32x8
     #define U16 U16x8
     #define U8   U8x8
-    #define F0 (F){0,0,0,0, 0,0,0,0}
-    #define F1 (F){1,1,1,1, 1,1,1,1}
+    #define F0 F{0,0,0,0, 0,0,0,0}
+    #define F1 F{1,1,1,1, 1,1,1,1}
 
     #define NS(id) id ## _hsw
     #define ATTR __attribute__((target("avx2,f16c")))
@@ -2024,7 +2024,8 @@
         }
 
         static bool hsw_ok() {
-            InitOnceExecuteOnce(&check_hsw_ok_once, check_hsw_ok_InitOnce_wrapper, NULL, NULL);
+            InitOnceExecuteOnce(&check_hsw_ok_once, check_hsw_ok_InitOnce_wrapper,
+                                nullptr, nullptr);
             return hsw_ok_;
         }
     #else
@@ -2059,16 +2060,16 @@
 
     if (curve->table_entries == 0) {
         return is_identity_tf(&curve->parametric)
-            ? (OpAndArg){ Op_noop, NULL }
-            : (OpAndArg){ ops[channel].parametric, &curve->parametric };
+            ? OpAndArg{ Op_noop, nullptr }
+            : OpAndArg{ ops[channel].parametric, &curve->parametric };
     } else if (curve->table_8) {
-        return (OpAndArg){ ops[channel].table_8,  curve };
+        return OpAndArg{ ops[channel].table_8,  curve };
     } else if (curve->table_16) {
-        return (OpAndArg){ ops[channel].table_16, curve };
+        return OpAndArg{ ops[channel].table_16, curve };
     }
 
     assert(false);
-    return (OpAndArg){Op_noop,NULL};
+    return OpAndArg{Op_noop,nullptr};
 }
 
 static size_t bytes_per_pixel(skcms_PixelFormat fmt) {
diff --git a/skcms.gni b/skcms.gni
index 2cfe2fb..a3def6e 100644
--- a/skcms.gni
+++ b/skcms.gni
@@ -4,7 +4,7 @@
 # found in the LICENSE file.
 
 skcms_sources = [
-  "skcms.c",
+  "skcms.cc",
   "skcms.h",
   "skcms_internal.h",
   "src/Transform_inl.h",
diff --git a/src/Transform_inl.h b/src/Transform_inl.h
index 6dc2a79..09183bf 100644
--- a/src/Transform_inl.h
+++ b/src/Transform_inl.h
@@ -72,12 +72,12 @@
 #elif defined(__clang__)
     #define CAST(T, v) __builtin_convertvector((v), T)
 #elif N == 4
-    #define CAST(T, v) (T){(v)[0],(v)[1],(v)[2],(v)[3]}
+    #define CAST(T, v) T{(v)[0],(v)[1],(v)[2],(v)[3]}
 #elif N == 8
-    #define CAST(T, v) (T){(v)[0],(v)[1],(v)[2],(v)[3], (v)[4],(v)[5],(v)[6],(v)[7]}
+    #define CAST(T, v) T{(v)[0],(v)[1],(v)[2],(v)[3], (v)[4],(v)[5],(v)[6],(v)[7]}
 #elif N == 16
-    #define CAST(T, v) (T){(v)[0],(v)[1],(v)[ 2],(v)[ 3], (v)[ 4],(v)[ 5],(v)[ 6],(v)[ 7], \
-                           (v)[8],(v)[9],(v)[10],(v)[11], (v)[12],(v)[13],(v)[14],(v)[15]}
+    #define CAST(T, v) T{(v)[0],(v)[1],(v)[ 2],(v)[ 3], (v)[ 4],(v)[ 5],(v)[ 6],(v)[ 7], \
+                         (v)[8],(v)[9],(v)[10],(v)[11], (v)[12],(v)[13],(v)[14],(v)[15]}
 #endif
 
 // When we convert from float to fixed point, it's very common to want to round,
@@ -247,28 +247,28 @@
     #define STORE_3(p, v) (p)[0] = v
     #define STORE_4(p, v) (p)[0] = v
 #elif N == 4 && !defined(USING_NEON)
-    #define LOAD_3(T, p) (T){(p)[0], (p)[3], (p)[6], (p)[ 9]}
-    #define LOAD_4(T, p) (T){(p)[0], (p)[4], (p)[8], (p)[12]};
+    #define LOAD_3(T, p) T{(p)[0], (p)[3], (p)[6], (p)[ 9]}
+    #define LOAD_4(T, p) T{(p)[0], (p)[4], (p)[8], (p)[12]};
     #define STORE_3(p, v) (p)[0] = (v)[0]; (p)[3] = (v)[1]; (p)[6] = (v)[2]; (p)[ 9] = (v)[3]
     #define STORE_4(p, v) (p)[0] = (v)[0]; (p)[4] = (v)[1]; (p)[8] = (v)[2]; (p)[12] = (v)[3]
 #elif N == 8
-    #define LOAD_3(T, p) (T){(p)[0], (p)[3], (p)[6], (p)[ 9],  (p)[12], (p)[15], (p)[18], (p)[21]}
-    #define LOAD_4(T, p) (T){(p)[0], (p)[4], (p)[8], (p)[12],  (p)[16], (p)[20], (p)[24], (p)[28]}
+    #define LOAD_3(T, p) T{(p)[0], (p)[3], (p)[6], (p)[ 9],  (p)[12], (p)[15], (p)[18], (p)[21]}
+    #define LOAD_4(T, p) T{(p)[0], (p)[4], (p)[8], (p)[12],  (p)[16], (p)[20], (p)[24], (p)[28]}
     #define STORE_3(p, v) (p)[ 0] = (v)[0]; (p)[ 3] = (v)[1]; (p)[ 6] = (v)[2]; (p)[ 9] = (v)[3]; \
                           (p)[12] = (v)[4]; (p)[15] = (v)[5]; (p)[18] = (v)[6]; (p)[21] = (v)[7]
     #define STORE_4(p, v) (p)[ 0] = (v)[0]; (p)[ 4] = (v)[1]; (p)[ 8] = (v)[2]; (p)[12] = (v)[3]; \
                           (p)[16] = (v)[4]; (p)[20] = (v)[5]; (p)[24] = (v)[6]; (p)[28] = (v)[7]
 #elif N == 16
     // TODO: revisit with AVX-512 gathers and scatters?
-    #define LOAD_3(T, p) (T){(p)[ 0], (p)[ 3], (p)[ 6], (p)[ 9], \
-                             (p)[12], (p)[15], (p)[18], (p)[21], \
-                             (p)[24], (p)[27], (p)[30], (p)[33], \
-                             (p)[36], (p)[39], (p)[42], (p)[45]}
+    #define LOAD_3(T, p) T{(p)[ 0], (p)[ 3], (p)[ 6], (p)[ 9], \
+                           (p)[12], (p)[15], (p)[18], (p)[21], \
+                           (p)[24], (p)[27], (p)[30], (p)[33], \
+                           (p)[36], (p)[39], (p)[42], (p)[45]}
 
-    #define LOAD_4(T, p) (T){(p)[ 0], (p)[ 4], (p)[ 8], (p)[12], \
-                             (p)[16], (p)[20], (p)[24], (p)[28], \
-                             (p)[32], (p)[36], (p)[40], (p)[44], \
-                             (p)[48], (p)[52], (p)[56], (p)[60]}
+    #define LOAD_4(T, p) T{(p)[ 0], (p)[ 4], (p)[ 8], (p)[12], \
+                           (p)[16], (p)[20], (p)[24], (p)[28], \
+                           (p)[32], (p)[36], (p)[40], (p)[44], \
+                           (p)[48], (p)[52], (p)[56], (p)[60]}
 
     #define STORE_3(p, v) \
         (p)[ 0] = (v)[ 0]; (p)[ 3] = (v)[ 1]; (p)[ 6] = (v)[ 2]; (p)[ 9] = (v)[ 3]; \
@@ -389,11 +389,11 @@
     #if N == 1
         *v = load_48_64(p,ix);
     #elif N == 4
-        *v = (U64){
+        *v = U64{
             load_48_64(p,ix[0]), load_48_64(p,ix[1]), load_48_64(p,ix[2]), load_48_64(p,ix[3]),
         };
     #elif N == 8 && !defined(__AVX2__)
-        *v = (U64){
+        *v = U64{
             load_48_64(p,ix[0]), load_48_64(p,ix[1]), load_48_64(p,ix[2]), load_48_64(p,ix[3]),
             load_48_64(p,ix[4]), load_48_64(p,ix[5]), load_48_64(p,ix[6]), load_48_64(p,ix[7]),
         };