Я читал эту статью в отношении undefined, и один из примеров "оптимизаций" выглядит очень сомнительным:
if (arg2 == 0) ereport(ERROR, (errcode(ERRCODE_DIVISION_BY_ZERO), errmsg("division by zero"))); /* No overflow is possible */ PG_RETURN_INT32((int32) arg1 / arg2);
Рисунок 2: неожиданная оптимизация исключает деление на ноль проверьте, в
src/backend/utils/adt/int8.c
PostgreSQL. Призыв кereport(ERROR, :::)
вызовет исключение.
По сути, компилятор предполагает, что ereport
вернется и удалит проверку arg2 == 0
, поскольку наличие деления подразумевает ненулевой знаменатель, т.е. arg2 != 0
.
Является ли это правильной оптимизацией? Является ли компилятор свободным предположить, что функция всегда будет возвращена?
EDIT: все зависит от ereport
, который описан таким образом:
84 /*----------
85 * New-style error reporting API: to be used in this way:
86 * ereport(ERROR,
87 * (errcode(ERRCODE_UNDEFINED_CURSOR),
88 * errmsg("portal \"%s\" not found", stmt->portalname),
89 * ... other errxxx() fields as needed ...));
90 *
91 * The error level is required, and so is a primary error message (errmsg
92 * or errmsg_internal). All else is optional. errcode() defaults to
93 * ERRCODE_INTERNAL_ERROR if elevel is ERROR or more, ERRCODE_WARNING
94 * if elevel is WARNING, or ERRCODE_SUCCESSFUL_COMPLETION if elevel is
95 * NOTICE or below.
96 *
97 * ereport_domain() allows a message domain to be specified, for modules that
98 * wish to use a different message catalog from the backend's. To avoid having
99 * one copy of the default text domain per .o file, we define it as NULL here
100 * and have errstart insert the default text domain. Modules can either use
101 * ereport_domain() directly, or preferably they can override the TEXTDOMAIN
102 * macro.
103 *
104 * If elevel >= ERROR, the call will not return; we try to inform the compiler
105 * of that via pg_unreachable(). However, no useful optimization effect is
106 * obtained unless the compiler sees elevel as a compile-time constant, else
107 * we're just adding code bloat. So, if __builtin_constant_p is available,
108 * use that to cause the second if() to vanish completely for non-constant
109 * cases. We avoid using a local variable because it not necessary and
110 * prevents gcc from making the unreachability deduction at optlevel -O0.
111 *----------