summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/char/char.cpp7
-rw-r--r--src/common/cxxstdio.hpp2
-rw-r--r--src/common/extract.hpp13
-rw-r--r--src/login/login.cpp34
-rw-r--r--src/map/battle.t.hpp2
-rw-r--r--src/map/clif.cpp6
-rw-r--r--src/map/magic-expr-eval.hpp8
-rw-r--r--src/map/magic-expr.cpp28
-rw-r--r--src/map/magic-interpreter-base.cpp4
-rw-r--r--src/map/map.t.hpp4
-rw-r--r--src/map/mob.cpp18
-rw-r--r--src/map/pc.cpp12
-rw-r--r--src/map/script.cpp19
-rw-r--r--src/map/skill.cpp22
-rw-r--r--src/warnings.hpp643
15 files changed, 727 insertions, 95 deletions
diff --git a/src/char/char.cpp b/src/char/char.cpp
index ed45b82..67003b5 100644
--- a/src/char/char.cpp
+++ b/src/char/char.cpp
@@ -3366,13 +3366,8 @@ int lan_config_read(const char *lancfgName)
// sub-network check of the map-server
{
- unsigned int a0, a1, a2, a3;
unsigned char p[4];
- sscanf(lan_map_ip, "%d.%d.%d.%d", &a0, &a1, &a2, &a3);
- p[0] = a0;
- p[1] = a1;
- p[2] = a2;
- p[3] = a3;
+ sscanf(lan_map_ip, "%hhu.%hhu.%hhu.%hhu", &p[0], &p[1], &p[2], &p[3]);
PRINTF("LAN test of LAN IP of the map-server: ");
if (lan_ip_check(p) == 0)
{
diff --git a/src/common/cxxstdio.hpp b/src/common/cxxstdio.hpp
index 6f5072e..d7c0634 100644
--- a/src/common/cxxstdio.hpp
+++ b/src/common/cxxstdio.hpp
@@ -67,7 +67,7 @@ namespace cxxstdio
return vsscanf(in, fmt, ap);
}
#else
- int do_vscan(const char *in, const char *fmt, va_list ap) = delete;
+ int do_vscan(const char *, const char *, va_list) = delete;
#endif
inline __attribute__((format(scanf, 2, 0)))
diff --git a/src/common/extract.hpp b/src/common/extract.hpp
index 52df9df..24456be 100644
--- a/src/common/extract.hpp
+++ b/src/common/extract.hpp
@@ -29,14 +29,9 @@ bool extract(const_string str, T *iv)
{
if (!str || str.size() > 20)
return false;
- switch (str.front())
- {
- case '-':
- case '0' ... '9':
- break;
- default:
- return false;
- }
+ if (!((str.front() == '-' && std::is_signed<T>::value)
+ || ('0' <= str.front() && str.front() <= '9')))
+ return false;
char buf[20 + 1];
std::copy(str.begin(), str.end(), buf);
buf[str.size()] = '\0';
@@ -53,8 +48,6 @@ bool extract(const_string str, T *iv)
}
else
{
- if (str.front() == '-')
- return false;
unsigned long long v = strtoull(buf, &end, 10);
if (errno || *end)
return false;
diff --git a/src/login/login.cpp b/src/login/login.cpp
index 3217af5..b8dc4d0 100644
--- a/src/login/login.cpp
+++ b/src/login/login.cpp
@@ -261,25 +261,23 @@ int read_gm_account(void)
static
int check_ipmask(struct in_addr ip, const char *str)
{
- unsigned int mask = 0, i = 0, m, ip2, a0, a1, a2, a3;
- unsigned char *p = (unsigned char *) &ip2, *p2 = (unsigned char *) &mask;
-
- if (sscanf(str, "%d.%d.%d.%d/%n", &a0, &a1, &a2, &a3, &i) != 4 || i == 0)
+ unsigned int mask = 0, ip2;
+ unsigned char *p = (unsigned char *) &ip2,
+ *p2 = (unsigned char *) &mask;
+ int i = 0;
+ unsigned int m;
+
+ if (sscanf(str, "%hhu.%hhu.%hhu.%hhu/%n",
+ &p[0], &p[1], &p[2], &p[3], &i) != 4
+ || i == 0)
return 0;
- p[0] = a0;
- p[1] = a1;
- p[2] = a2;
- p[3] = a3;
- if (sscanf(str + i, "%d.%d.%d.%d", &a0, &a1, &a2, &a3) == 4)
+ if (sscanf(str + i, "%hhu.%hhu.%hhu.%hhu",
+ &p2[0], &p2[1], &p2[2], &p2[3]) == 4)
{
- p2[0] = a0;
- p2[1] = a1;
- p2[2] = a2;
- p2[3] = a3;
mask = ntohl(mask);
}
- else if (sscanf(str + i, "%d", &m) == 1 && m <= 32)
+ else if (sscanf(str + i, "%u", &m) == 1 && m <= 32)
{
for (i = 0; i < m && i < 32; i++)
mask = (mask >> 1) | 0x80000000;
@@ -3662,13 +3660,9 @@ int login_lan_config_read(const char *lancfgName)
// sub-network check of the char-server
{
- unsigned int a0, a1, a2, a3;
unsigned char p[4];
- sscanf(lan_char_ip, "%d.%d.%d.%d", &a0, &a1, &a2, &a3);
- p[0] = a0;
- p[1] = a1;
- p[2] = a2;
- p[3] = a3;
+ sscanf(lan_char_ip, "%hhu.%hhu.%hhu.%hhu",
+ &p[0], &p[1], &p[2], &p[3]);
PRINTF("LAN test of LAN IP of the char-server: ");
if (lan_ip_check(p) == 0)
{
diff --git a/src/map/battle.t.hpp b/src/map/battle.t.hpp
index b0222a2..b84d1f2 100644
--- a/src/map/battle.t.hpp
+++ b/src/map/battle.t.hpp
@@ -62,7 +62,7 @@ BCT& operator ^= (BCT& l, BCT r) { return l = l & r; }
// BCT operator ~(BCT r);
constexpr
-bool operator == (BCT l, BCT r) { return l.lo == r.lo && l.mid == r.mid && l.classic == r.classic && l.level == r.level && l.unused == r.unused; };
+bool operator == (BCT l, BCT r) { return l.lo == r.lo && l.mid == r.mid && l.classic == r.classic && l.level == r.level && l.unused == r.unused; }
constexpr
bool operator != (BCT l, BCT r) { return !(l == r); }
diff --git a/src/map/clif.cpp b/src/map/clif.cpp
index cfa5c5b..e306c23 100644
--- a/src/map/clif.cpp
+++ b/src/map/clif.cpp
@@ -1007,8 +1007,8 @@ int clif_npc0078(struct npc_data *nd, unsigned char *buf)
/* These indices are derived from equip_pos in pc.c and some guesswork */
static
-earray<EQUIP, LOOK, LOOK::COUNT> equip_points =
-{
+earray<EQUIP, LOOK, LOOK::COUNT> equip_points //=
+{{
EQUIP::NONE, // base
EQUIP::NONE, // hair
EQUIP::WEAPON, // weapon
@@ -1023,7 +1023,7 @@ earray<EQUIP, LOOK, LOOK::COUNT> equip_points =
EQUIP::CAPE, // cape
EQUIP::MISC1, // misc1
EQUIP::MISC2, // misc2
-};
+}};
/*==========================================
*
diff --git a/src/map/magic-expr-eval.hpp b/src/map/magic-expr-eval.hpp
index da9a0a4..0bf9ee4 100644
--- a/src/map/magic-expr-eval.hpp
+++ b/src/map/magic-expr-eval.hpp
@@ -4,11 +4,11 @@
/* Helper definitions for dealing with functions and operations */
static
-earray<int, DIR, DIR::COUNT> heading_x =
-{ 0, -1, -1, -1, 0, 1, 1, 1 };
+earray<int, DIR, DIR::COUNT> heading_x //=
+{{ 0, -1, -1, -1, 0, 1, 1, 1 }};
static
-earray<int, DIR, DIR::COUNT> heading_y =
-{ 1, 1, 0, -1, -1, -1, 0, 1 };
+earray<int, DIR, DIR::COUNT> heading_y //=
+{{ 1, 1, 0, -1, -1, -1, 0, 1 }};
int magic_signature_check(const char *opname, const char *funname, const char *signature,
int args_nr, val_t *args, int line, int column);
diff --git a/src/map/magic-expr.cpp b/src/map/magic-expr.cpp
index d544234..904d4a4 100644
--- a/src/map/magic-expr.cpp
+++ b/src/map/magic-expr.cpp
@@ -612,18 +612,18 @@ int fun_get_##name(env_t *, int, val_t *result, val_t *args) \
return 0; \
}
-BATTLE_GETTER(str);
-BATTLE_GETTER(agi);
-BATTLE_GETTER(vit);
-BATTLE_GETTER(dex);
-BATTLE_GETTER(luk);
-BATTLE_GETTER(int);
-BATTLE_GETTER(lv);
-BATTLE_GETTER(hp);
-BATTLE_GETTER(mdef);
-BATTLE_GETTER(def);
-BATTLE_GETTER(max_hp);
-BATTLE_GETTER(dir);
+BATTLE_GETTER(str)
+BATTLE_GETTER(agi)
+BATTLE_GETTER(vit)
+BATTLE_GETTER(dex)
+BATTLE_GETTER(luk)
+BATTLE_GETTER(int)
+BATTLE_GETTER(lv)
+BATTLE_GETTER(hp)
+BATTLE_GETTER(mdef)
+BATTLE_GETTER(def)
+BATTLE_GETTER(max_hp)
+BATTLE_GETTER(dir)
#define MMO_GETTER(name) \
static \
@@ -636,8 +636,8 @@ int fun_get_##name(env_t *, int, val_t *result, val_t *args) \
return 0; \
}
-MMO_GETTER(sp);
-MMO_GETTER(max_sp);
+MMO_GETTER(sp)
+MMO_GETTER(max_sp)
static
int fun_name_of(env_t *, int, val_t *result, val_t *args)
diff --git a/src/map/magic-interpreter-base.cpp b/src/map/magic-interpreter-base.cpp
index e970eb2..f0fc6e9 100644
--- a/src/map/magic-interpreter-base.cpp
+++ b/src/map/magic-interpreter-base.cpp
@@ -16,7 +16,7 @@ void set_int_p(val_t *v, int i, TY t)
#define SETTER(tty, dyn_ty, field) (val_t *v, tty x) { v->ty = dyn_ty; v->v.field = x; }
static
-void set_string SETTER(char *, TY_STRING, v_string);
+void set_string SETTER(char *, TY_STRING, v_string)
static
void set_entity(val_t *v, entity_t *e)
@@ -33,7 +33,7 @@ void set_invocation(val_t *v, invocation_t *i)
}
static
-void set_spell SETTER(spell_t *, TY_SPELL, v_spell);
+void set_spell SETTER(spell_t *, TY_SPELL, v_spell)
#define setenv(f, v, x) f(&(env->vars[v]), x)
diff --git a/src/map/map.t.hpp b/src/map/map.t.hpp
index 027a394..b511806 100644
--- a/src/map/map.t.hpp
+++ b/src/map/map.t.hpp
@@ -504,13 +504,13 @@ constexpr
SP sp_to_usp(SP sp)
{
return attr_to_usp(sp_to_attr(sp));
-};
+}
constexpr
SP usp_to_sp(SP sp)
{
return attr_to_sp(usp_to_attr(sp));
-};
+}
enum class LOOK : uint8_t
diff --git a/src/map/mob.cpp b/src/map/mob.cpp
index 7c26ceb..df739a8 100644
--- a/src/map/mob.cpp
+++ b/src/map/mob.cpp
@@ -122,8 +122,8 @@ int mob_spawn_dataset(struct mob_data *md, const char *mobname, int mob_class)
// For one 256th of change, we give out that many 1024th fractions of XP change
// (i.e., 1024 means a 100% XP increase for a single point of adjustment, 4 means 100% XP bonus for doubling the value)
static
-earray<int, mob_stat, MOB_XP_BONUS> mutation_value =
-{
+earray<int, mob_stat, MOB_XP_BONUS> mutation_value //=
+{{
2, // MOB_LV
3, // MOB_MAX_HP
1, // MOB_STR
@@ -138,13 +138,13 @@ earray<int, mob_stat, MOB_XP_BONUS> mutation_value =
2, // MOB_DEF
2, // MOB_MDEF
2, // MOB_SPEED
-};
+}};
// The mutation scale indicates how far `up' we can go, with 256 indicating 100% Note that this may stack with multiple
// calls to `mutate'.
static
-earray<int, mob_stat, MOB_XP_BONUS> mutation_scale =
-{
+earray<int, mob_stat, MOB_XP_BONUS> mutation_scale //=
+{{
16, // MOB_LV
256, // MOB_MAX_HP
32, // MOB_STR
@@ -159,7 +159,7 @@ earray<int, mob_stat, MOB_XP_BONUS> mutation_scale =
48, // MOB_DEF
48, // MOB_MDEF
80, // MOB_SPEED
-};
+}};
// The table below indicates the `average' value for each of the statistics, or -1 if there is none.
// This average is used to determine XP modifications for mutations. The experience point bonus is
@@ -169,8 +169,8 @@ earray<int, mob_stat, MOB_XP_BONUS> mutation_scale =
// (3) third, compute the percentage stat change relative to mutation_base (p1)
// (4) fourth, compute the XP mofication based on the smaller of (p0, p1).
static
-earray<int, mob_stat, MOB_XP_BONUS> mutation_base =
-{
+earray<int, mob_stat, MOB_XP_BONUS> mutation_base //=
+{{
30, // MOB_LV
-1, // MOB_MAX_HP
20, // MOB_STR
@@ -185,7 +185,7 @@ earray<int, mob_stat, MOB_XP_BONUS> mutation_base =
-1, // MOB_DEF
20, // MOB_MDEF
-1, // MOB_SPEED
-};
+}};
/*========================================
* Mutates a MOB. For large `direction' values, calling this multiple times will give bigger XP boni.
diff --git a/src/map/pc.cpp b/src/map/pc.cpp
index c25f512..5780525 100644
--- a/src/map/pc.cpp
+++ b/src/map/pc.cpp
@@ -102,8 +102,8 @@ static
int diry[8] = { 1, 1, 0, -1, -1, -1, 0, 1 };
static
-earray<EPOS, EQUIP, EQUIP::COUNT> equip_pos =
-{
+earray<EPOS, EQUIP, EQUIP::COUNT> equip_pos //=
+{{
EPOS::MISC2,
EPOS::CAPE,
EPOS::SHOES,
@@ -115,7 +115,7 @@ earray<EPOS, EQUIP, EQUIP::COUNT> equip_pos =
EPOS::SHIELD,
EPOS::WEAPON,
EPOS::ARROW,
-};
+}};
//static struct dbt *gm_account_db;
static
@@ -4870,12 +4870,12 @@ int pc_gainexp_reason(struct map_session_data *sd, int base_exp, int job_exp,
if ((battle_config.pvp_exp == 0) && map[sd->bl.m].flag.pvp) // [MouseJstr]
return 0; // no exp on pvp maps
- earray<const char *, PC_GAINEXP_REASON, PC_GAINEXP_REASON::COUNT> reasons =
- {
+ earray<const char *, PC_GAINEXP_REASON, PC_GAINEXP_REASON::COUNT> reasons //=
+ {{
"KILLXP",
"HEALXP",
"SCRIPTXP",
- };
+ }};
MAP_LOG_PC(sd, "GAINXP %d %d %s", base_exp, job_exp, reasons[reason]);
if (sd->sc_data[SC_RICHMANKIM].timer != -1)
diff --git a/src/map/script.cpp b/src/map/script.cpp
index 5411e59..25db80b 100644
--- a/src/map/script.cpp
+++ b/src/map/script.cpp
@@ -851,14 +851,21 @@ void read_constdb(void)
if (line[0] == '/' && line[1] == '/')
continue;
- std::string name;
+ char *name = nullptr;
int val;
int type = 0; // if not provided
- if (SSCANF(line, "%m[A-Za-z0-9_] %x %x", &name, &val, &type) < 2)
- continue;
- for (char& c : name)
- c = tolower(c);
- int n = add_str(name.c_str());
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat"
+ if (sscanf(line.c_str(), "%m[A-Za-z0-9_] %i %i", &name, &val, &type) < 2)
+ {
+ free(name);
+ continue;
+ }
+#pragma GCC diagnostic pop
+ for (char *p = name; *p; ++p)
+ *p = tolower(*p);
+ int n = add_str(name);
+ free(name);
str_data[n].type = type ? ScriptCode::PARAM : ScriptCode::INT;
str_data[n].val = val;
}
diff --git a/src/map/skill.cpp b/src/map/skill.cpp
index 77da219..68f27fc 100644
--- a/src/map/skill.cpp
+++ b/src/map/skill.cpp
@@ -25,8 +25,8 @@
// This table appears to be wrong
/* スキル番号=>ステータス異常番号変換テーブル */
-earray<StatusChange, SkillID, MAX_SKILL_DB> SkillStatusChangeTable =
-{
+earray<StatusChange, SkillID, MAX_SKILL_DB> SkillStatusChangeTable //=
+{{
// 0-
StatusChange::NEGATIVE1,
StatusChange::NEGATIVE1,
@@ -489,7 +489,7 @@ earray<StatusChange, SkillID, MAX_SKILL_DB> SkillStatusChangeTable =
StatusChange::NEGATIVE1,
StatusChange::NEGATIVE1,
StatusChange::NEGATIVE1,
-};
+}};
struct skill_name_db skill_names[] =
{
@@ -1711,8 +1711,8 @@ int skill_additional_effect(struct block_list *src, struct block_list *bl,
&& skillid != MC_CARTREVOLUTION
&& bool(attack_type & BF_WEAPON)))
return 0;
- earray<int, BadSC, BadSC::COUNT> arr_sc_def_card1 =
- {
+ earray<int, BadSC, BadSC::COUNT> arr_sc_def_card1 //=
+ {{
sc_def_mdef, // stone
sc_def_mdef, // freeze
sc_def_vit, // stan
@@ -1722,8 +1722,8 @@ int skill_additional_effect(struct block_list *src, struct block_list *bl,
sc_def_vit, // silence
sc_def_int, // confusion
sc_def_int, // blind
- }, arr_sc_def_card2 =
- {
+ }}, arr_sc_def_card2 //=
+ {{
sc_def_mdef2, // stone
sc_def_mdef2, // freeze
sc_def_vit2, // stan
@@ -1733,10 +1733,10 @@ int skill_additional_effect(struct block_list *src, struct block_list *bl,
sc_def_vit2, // silence
sc_def_int2, // confusion
sc_def_int2, // blind
- };
+ }};
- earray<SkillID, BadSC, BadSC::COUNT> sc2 =
- {
+ earray<SkillID, BadSC, BadSC::COUNT> sc2 //=
+ {{
MG_STONECURSE, // stone
MG_FROSTDIVER, // freeze
NPC_STUNATTACK, // stan
@@ -1746,7 +1746,7 @@ int skill_additional_effect(struct block_list *src, struct block_list *bl,
NPC_SILENCEATTACK, // silence
SkillID::ZERO, // confusion
NPC_BLINDATTACK, // blind
- };
+ }};
for (BadSC bi : erange(BadSC(), BadSC::COUNT))
{
diff --git a/src/warnings.hpp b/src/warnings.hpp
new file mode 100644
index 0000000..63dd79b
--- /dev/null
+++ b/src/warnings.hpp
@@ -0,0 +1,643 @@
+// no include guards
+// This is the first file in every compilation, passed by the makefile.
+// This file contains only preprocessor directions.
+
+// This file is currently targeted at:
+// GCC 4.6 (incomplete due to bugs)
+// GCC 4.7 (for few minor workarounds)
+// GCC 4.8 (zarro boogs found)
+// clang 3.1 (may ICE later)
+// clang 3.2 (with a few major workarounds)
+
+// List of warnings that require arguments,
+// and thus cannot reliably be activated:
+// gcc 4.6:
+// -Wlarger-than=<1024>
+// -Wnormalized=<id|nfc|nfd>
+// -Wsuggest-attribute=<noreturn,const,pure,format>
+// gcc 4.7:
+// -Wstack-usage=<8192>
+// ???
+// -Wstrict-aliasing=<1>
+// -Wstrict-overflow=<1>
+
+// options that enable other options
+// only warnings so I can catch the errors
+#pragma GCC diagnostic warning "-Wall"
+#pragma GCC diagnostic warning "-Wextra"
+#pragma GCC diagnostic warning "-Wunused"
+#pragma GCC diagnostic warning "-Wformat"
+
+#ifdef __clang__
+# if __clang_major__ < 3
+# error "your clang is way too old"
+# elif __clang_major == 3
+# if __clang_minor__ < 1
+# error "your clang is too old"
+# endif // __clang_minor__
+# endif // __clang_major__
+#else // __clang__
+# if __GNUC__ < 4
+# error "your gcc is way too old"
+# if __GNUC_MINOR__ < 6
+# error "your gcc is too old"
+# elif __GNUC_MINOR__ == 6
+# if __GNUC_PATCHLEVEL__ < 3
+# error "TODO: test this patchlevel"
+# endif // __GNUC_PATCHLEVEL__
+# elif __GNUC_MINOR__ == 7
+# if __GNUC_PATCHLEVEL__ < 2
+# error "your gcc has a known bad patchlevel"
+# endif // __GNUC_PATCHLEVEL__
+# endif // __GNUC_MINOR__
+# endif // __GNUC__
+#endif // __clang__
+
+// BEGIN Macros to make my life easier
+
+// stringification requirement - #sw within #ar
+#define P(ar) _Pragma(#ar)
+
+// Use "GCC diagnostic" for warnings applicable to all versions.
+#define I(sw) P(GCC diagnostic ignored #sw)
+#define W(sw) P(GCC diagnostic warning #sw)
+#define E(sw) P(GCC diagnostic error #sw)
+// configurable thing (also change in clang below!)
+#define X(sw) I(sw)
+
+
+#ifdef __clang__
+
+// Use "clang diagnostic" for warnings specific to clang
+# define IC(sw) P(clang diagnostic ignored #sw)
+# define WC(sw) P(clang diagnostic warning #sw)
+# define EC(sw) P(clang diagnostic error #sw)
+# define XC(sw) IC(sw) // this is below
+
+// warning specific to gcc
+# define IG(sw) static_assert('I', #sw "skipped for clang");
+# define WG(sw) static_assert('W', #sw "skipped for clang");
+# define EG(sw) static_assert('E', #sw "skipped for clang");
+# define XG(sw) static_assert('X', #sw "skipped for clang");
+
+# define IG47(sw) static_assert('I', #sw "only for gcc 4.7+");
+# define WG47(sw) static_assert('W', #sw "only for gcc 4.7+");
+# define EG47(sw) static_assert('E', #sw "only for gcc 4.7+");
+# define XG47(sw) static_assert('X', #sw "only for gcc 4.7+");
+
+# define IG48(sw) static_assert('I', #sw "only for gcc 4.8+");
+# define WG48(sw) static_assert('W', #sw "only for gcc 4.8+");
+# define EG48(sw) static_assert('E', #sw "only for gcc 4.8+");
+# define XG48(sw) static_assert('X', #sw "only for gcc 4.8+");
+
+# define I47(sw) I(sw)
+# define W47(sw) W(sw)
+# define E47(sw) E(sw)
+# define X47(sw) X(sw)
+
+# define I48(sw) I(sw)
+# define W48(sw) W(sw)
+# define E48(sw) E(sw)
+# define X48(sw) X(sw)
+
+#else
+
+// warnings specific to clang
+# define IC(sw) static_assert('I', #sw "skipped for gcc");
+# define WC(sw) static_assert('W', #sw "skipped for gcc");
+# define EC(sw) static_assert('E', #sw "skipped for gcc");
+# define XC(sw) static_assert('X', #sw "skipped for gcc");
+
+// warnings specific to gcc
+# define IG(sw) I(sw)
+# define WG(sw) W(sw)
+# define EG(sw) E(sw)
+# define XG(sw) X(sw)
+
+// used both for warnings not implemented in a version
+// and for warnings that falsely trigger
+# if __GNUC__ == 4
+# if __GNUC_MINOR__ >= 7
+# define IG47(sw) IG(sw)
+# define WG47(sw) WG(sw)
+# define EG47(sw) EG(sw)
+# define XG47(sw) XG(sw)
+
+# define I47(sw) I(sw)
+# define W47(sw) W(sw)
+# define E47(sw) E(sw)
+# define X47(sw) X(sw)
+# else
+# define IG47(sw) static_assert('I', #sw "only for gcc 4.7+");
+# define WG47(sw) static_assert('W', #sw "only for gcc 4.7+");
+# define EG47(sw) static_assert('E', #sw "only for gcc 4.7+");
+# define XG47(sw) static_assert('X', #sw "only for gcc 4.7+");
+
+# define I47(sw) static_assert('I', #sw "only for gcc 4.7+ or clang");
+# define W47(sw) static_assert('W', #sw "only for gcc 4.7+ or clang");
+# define E47(sw) static_assert('E', #sw "only for gcc 4.7+ or clang");
+# define X47(sw) static_assert('X', #sw "only for gcc 4.7+ or clang");
+# endif // __GNUC_MINOR__
+# if __GNUC_MINOR__ >= 8
+# define IG48(sw) IG(sw)
+# define WG48(sw) WG(sw)
+# define EG48(sw) EG(sw)
+# define XG48(sw) XG(sw)
+
+# define I48(sw) IG(sw)
+# define W48(sw) WG(sw)
+# define E48(sw) EG(sw)
+# define X48(sw) XG(sw)
+# else
+# define IG48(sw) static_assert('I', #sw "only for gcc 4.8+");
+# define WG48(sw) static_assert('W', #sw "only for gcc 4.8+");
+# define EG48(sw) static_assert('E', #sw "only for gcc 4.8+");
+# define XG48(sw) static_assert('X', #sw "only for gcc 4.8+");
+
+# define I48(sw) static_assert('I', #sw "only for gcc 4.8+ or clang");
+# define W48(sw) static_assert('W', #sw "only for gcc 4.8+ or clang");
+# define E48(sw) static_assert('E', #sw "only for gcc 4.8+ or clang");
+# define X48(sw) static_assert('X', #sw "only for gcc 4.8+ or clang");
+# endif // __GNUC_MINOR__
+# endif // __GNUC__
+#endif // __clang__
+
+// END macros to make my life easier
+
+
+/// Warn about things that will change when compiling
+/// with an ABI-compliant compiler
+X(-Wabi)
+
+/// Warn if a subobject has an abi_tag attribute that
+/// the complete object type does not have
+WG48(-Wabi-tag)
+
+/// Warn about suspicious uses of memory addresses
+E(-Waddress)
+
+/// Warn about returning structures, unions or arrays
+X(-Waggregate-return)
+
+/// Warn if an array is accessed out of bounds
+E(-Warray-bounds)
+
+/// Warn about inappropriate attribute usage
+E(-Wattributes)
+
+/// Warn when a built-in preprocessor macro is
+// undefined or redefined
+E(-Wbuiltin-macro-redefined)
+
+/// Warn about C++ constructs whose meaning differs
+/// between ISO C++ 1998 and ISO C++ 2011
+E(-Wc++0x-compat)
+//W(-Wc++11-compat)
+
+/// Warn about pointer casts which increase alignment
+X(-Wcast-align)
+
+/// Warn about casts which discard qualifiers
+X(-Wcast-qual)
+
+/// Warn about subscripts whose type is "char"
+E(-Wchar-subscripts)
+
+/// Warn about variables that might be changed by
+/// "longjmp" or "vfork"
+EG(-Wclobbered)
+
+/// Warn about possibly nested block comments, and
+/// C++ comments spanning more than one physical line
+E(-Wcomment)
+
+/// Warn for implicit type conversions that may
+/// change a value
+X(-Wconversion)
+
+/// Warn for converting NULL from/to a non-pointer
+/// type
+X(-Wconversion-null)
+
+/// Warn in case profiles in -fprofile-use do not
+/// match
+WG(-Wcoverage-mismatch)
+
+/// Warn when a #warning directive is encountered
+EG(-Wcpp)
+
+/// Warn when all constructors and destructors are
+/// private
+X(-Wctor-dtor-privacy)
+
+/// Warn about deleting polymorphic objects with non-
+/// virtual destructors
+E47(-Wdelete-non-virtual-dtor)
+
+/// Warn if a deprecated compiler feature, class,
+/// method, or field is used
+W(-Wdeprecated)
+
+/// Warn about uses of __attribute__((deprecated))
+/// declarations
+W(-Wdeprecated-declarations)
+
+/// Warn when an optimization pass is disabled
+X(-Wdisabled-optimization)
+
+/// Warn about compile-time integer division by zero
+E(-Wdiv-by-zero)
+
+/// Warn about implicit conversions from "float" to
+/// "double"
+XG(-Wdouble-promotion)
+
+/// Warn about violations of Effective C++ style rules
+X(-Weffc++)
+
+/// Warn about an empty body in an if or else
+/// statement
+E(-Wempty-body)
+
+/// Warn about stray tokens after #elif and #endif
+E(-Wendif-labels)
+
+/// Warn about comparison of different enum types
+E(-Wenum-compare)
+
+/// Warn if testing floating point numbers for
+/// equality
+X(-Wfloat-equal)
+
+/// Warn about printf/scanf/strftime/strfmon format
+/// string anomalies
+// see below
+EG(-Wformat)
+
+/// Warn about format strings that contain NUL bytes
+EG(-Wformat-contains-nul)
+
+/// Warn if passing too many arguments to a function
+/// for its format string
+E(-Wformat-extra-args)
+
+/// Warn about format strings that are not literals
+// Available in clang, but not smart enough to handle constexpr.
+EG(-Wformat-nonliteral)
+
+/// Warn about possible security problems with format
+/// functions
+// Same.
+EG(-Wformat-security)
+
+/// Warn about strftime formats yielding 2-digit years
+E(-Wformat-y2k)
+
+/// Warn about zero-length formats
+I(-Wformat-zero-length)
+
+/// Warn when attempting to free a non-heap object
+EG47(-Wfree-nonheap-object)
+
+// -Wgnu is a clang alias for -Wpedantic
+
+/// Warn whenever type qualifiers are ignored.
+E(-Wignored-qualifiers)
+
+/// Warn about C++11 inheriting constructors when the
+/// base has a variadic constructor
+WG48(-Winherited-variadic-ctor)
+
+/// Warn about variables which are initialized to
+/// themselves
+X(-Winit-self)
+
+/// Warn when an inlined function cannot be inlined
+X(-Winline)
+
+/// Warn when there is a cast to a pointer from an
+/// integer of a different size
+E(-Wint-to-pointer-cast)
+
+/// Warn when an atomic memory model parameter is
+/// known to be outside the valid range.
+WG47(-Winvalid-memory-model)
+
+/// Warn about invalid uses of the "offsetof" macro
+E(-Winvalid-offsetof)
+
+/// Warn about PCH files that are found but not used
+X(-Winvalid-pch)
+
+/// Warn when a string or character literal is
+/// followed by a ud-suffix which does not begin with
+/// an underscore.
+WG48(-Wliteral-suffix)
+
+/// Warn when a logical operator is suspiciously
+/// always evaluating to true or false
+WG(-Wlogical-op)
+
+/// Do not warn about using "long long" when -pedantic
+X(-Wlong-long)
+
+/// Warn about suspicious declarations of "main"
+E(-Wmain)
+
+/// Warn about maybe uninitialized automatic variables
+EG47(-Wmaybe-uninitialized)
+
+/// Warn about possibly missing braces around
+/// initializers
+// beware of things like std::array!
+E(-Wmissing-braces)
+
+/// Warn about global functions without previous
+/// declarations
+E(-Wmissing-declarations)
+
+/// Warn about missing fields in struct initializers
+// Actually supported by GCC, but gives warnings when I don't want, e.g.:
+// Foo foo = {};
+EC(-Wmissing-field-initializers)
+IG(-Wmissing-field-initializers)
+
+/// Warn about functions which might be candidates
+/// for format attributes
+X(-Wmissing-format-attribute)
+
+/// Warn about user-specified include directories
+/// that do not exist
+X(-Wmissing-include-dirs)
+
+/// Warn about functions which might be candidates
+/// for __attribute__((noreturn))
+X(-Wmissing-noreturn)
+
+/// Warn about constructs not instrumented by
+/// -fmudflap
+EG(-Wmudflap)
+
+/// Warn about use of multi-character character
+/// constants
+E(-Wmultichar)
+
+/// Warn about narrowing conversions within { } that
+/// are ill-formed in C++11
+EG47(-Wnarrowing)
+
+/// Warn when a noexcept expression evaluates to
+/// false even though the expression can't actually
+/// throw
+WG(-Wnoexcept)
+
+/// Warn when non-templatized friend functions are
+/// declared within a template
+EG(-Wnon-template-friend)
+
+/// Warn about non-virtual destructors
+X(-Wnon-virtual-dtor)
+
+/// Warn about NULL being passed to argument slots
+/// marked as requiring non-NULL
+E(-Wnonnull)
+
+/// Warn if a C-style cast is used in a program
+X(-Wold-style-cast)
+
+/// Warn about overflow in arithmetic expressions
+W(-Woverflow)
+
+/// Warn if a string is longer than the maximum
+/// portable length specified by the standard
+//X(-Woverlength-strings)
+
+/// Warn about overloaded virtual function names
+X(-Woverloaded-virtual)
+
+/// Warn when the packed attribute has no effect on
+/// struct layout
+X(-Wpacked)
+
+/// Warn about packed bit-fields whose offset changed
+/// in GCC 4.4
+WG(-Wpacked-bitfield-compat)
+
+/// Warn when padding is required to align structure
+/// members
+X(-Wpadded)
+
+/// Warn about possibly missing parentheses
+E(-Wparentheses)
+
+/// Issue warnings needed for strict compliance to
+/// the standard
+EG48(-Wpedantic)
+WC(-Wpedantic)
+
+/// Warn when converting the type of pointers to
+/// member functions
+EG(-Wpmf-conversions)
+
+/// Warn about function pointer arithmetic
+X(-Wpointer-arith)
+
+/// Warn about misuses of pragmas
+EG(-Wpragmas)
+
+/// Warn about multiple declarations of the same
+/// object
+W(-Wredundant-decls)
+
+/// Warn when the compiler reorders code
+E(-Wreorder)
+
+/// Warn about returning a pointer/reference to a
+/// local or temporary variable.
+WG48(-Wreturn-local-addr)
+
+/// Warn whenever a function's return type defaults
+/// to "int" (C), or about inconsistent return types
+/// (C++)
+E(-Wreturn-type)
+
+/// Warn about possible violations of sequence point
+/// rules
+E(-Wsequence-point)
+
+/// Warn when one local variable shadows another
+X(-Wshadow)
+
+/// Warn about signed-unsigned comparisons
+X(-Wsign-compare)
+
+/// Warn when overload promotes from unsigned to
+/// signed
+X(-Wsign-promo)
+
+/// This switch lacks documentation
+WG48(-Wsizeof-pointer-memaccess)
+
+/// Warn when not issuing stack smashing protection
+/// for some reason
+X(-Wstack-protector)
+
+/// Warn about code which might break strict aliasing
+/// rules
+E(-Wstrict-aliasing)
+
+/// Warn about uncasted NULL used as sentinel
+WG(-Wstrict-null-sentinel)
+
+/// Warn about optimizations that assume that signed
+/// overflow is undefined
+X(-Wstrict-overflow)
+
+/// Warn about enumerated switches, with no default,
+/// missing a case
+X(-Wswitch)
+
+/// Warn about enumerated switches missing a
+/// "default:" statement
+X(-Wswitch-default)
+
+/// Warn about all enumerated switches missing a
+/// specific case
+X(-Wswitch-enum)
+
+/// Warn when __sync_fetch_and_nand and
+/// __sync_nand_and_fetch built-in functions are used
+WG(-Wsync-nand)
+
+/// Warn whenever a trampoline is generated
+EG(-Wtrampolines)
+
+/// Warn if trigraphs are encountered that might
+/// affect the meaning of the program
+E(-Wtrigraphs)
+
+/// Warn if a comparison is always true or always
+/// false due to the limited range of the data type
+E(-Wtype-limits)
+
+/// Warn if an undefined macro is used in an #if
+/// directive
+X(-Wundef)
+
+/// Warn about uninitialized automatic variables
+E(-Wuninitialized)
+
+/// Warn about unrecognized pragmas
+E(-Wunknown-pragmas)
+
+/// Warn if the loop cannot be optimized due to
+/// nontrivial assumptions.
+XG(-Wunsafe-loop-optimizations)
+
+/// Warn when a function parameter is only set,
+/// otherwise unused
+EG(-Wunused-but-set-parameter)
+
+/// Warn when a variable is only set, otherwise unused
+EG(-Wunused-but-set-variable)
+
+/// Warn when a function is unused
+E(-Wunused-function)
+
+/// Warn when a label is unused
+E(-Wunused-label)
+
+/// Warn when typedefs locally defined in a function
+/// are not used
+EG47(-Wunused-local-typedefs)
+
+/// Warn about macros defined in the main file that
+/// are not used
+X(-Wunused-macros)
+
+/// Warn when a function parameter is unused
+E(-Wunused-parameter)
+
+/// Warn if a caller of a function, marked with
+/// attribute warn_unused_result, does not use its
+/// return value
+X(-Wunused-result)
+
+/// Warn when an expression value is unused
+E(-Wunused-value)
+
+/// Warn when a variable is unused
+E(-Wunused-variable)
+
+/// Warn about useless casts
+XG48(-Wuseless-cast)
+
+/// Warn about questionable usage of the macros used
+/// to retrieve variable arguments
+EG48(-Wvarargs)
+
+/// Warn about using variadic macros
+X(-Wvariadic-macros)
+
+/// Warn when a vector operation is compiled
+/// outside the SIMD
+WG47(-Wvector-operation-performance)
+
+/// Warn if a virtual base has a non-trivial move
+/// assignment operator
+EG48(-Wvirtual-move-assign)
+
+/// Warn if a variable length array is used
+I(-Wvla)
+
+/// Warn when a register variable is declared volatile
+E(-Wvolatile-register-var)
+
+/// In C++, nonzero means warn about deprecated
+/// conversion from string literals to 'char *'. In
+/// C, similar warning, except that the conversion is
+/// of course not deprecated by the ISO C standard.
+E(-Wwrite-strings)
+
+/// Warn when a literal '0' is used as null
+/// pointer
+XG47(-Wzero-as-null-pointer-constant)
+
+
+// clean up after myself
+#undef P
+
+#undef I
+#undef W
+#undef E
+#undef X
+
+#undef IC
+#undef WC
+#undef EC
+#undef XC
+
+#undef IG
+#undef WG
+#undef EG
+#undef XG
+
+#undef IG47
+#undef WG47
+#undef EG47
+#undef XG47
+
+#undef IG48
+#undef WG48
+#undef EG48
+#undef XG48
+
+#undef I47
+#undef W47
+#undef E47
+#undef X47
+
+#undef I48
+#undef W48
+#undef E48
+#undef X48