Я прочитал, что он используется для оптимизации, но четко не определен ни в одном стандарте.
blockquote>Фактически это является , четко определенным C. Цитирование N1570 draft раздела 6.7.1, пункт 6 (другие версии имеют одинаковую формулировку):
Объявление идентификатора для объекта с спецификатором класса хранения
blockquote>register
предполагает, что доступ к объекту должен быть как можно быстрее. Степень, в которой такие предложения эффективны, определяется реализацией.Унарный оператор
&
не может применяться к объекту, определенному с помощьюregister
, аregister
может не быть используется в внешней декларации.Существует несколько других (довольно неясных) правил, специфичных для
register
-qualified objects:
- Определение объекта массива с помощью
register
имеет неопределенное поведение. Исправление: законно задавать объект массива с помощьюregister
, но вы не можете ничего использовать с таким объектом (индексирование в массив требует ввода адреса его начального элемента)._Alignas
(новый в C11) не может быть применен к такому объекту.- Если имя параметра, переданное макросу
va_start
, [register
-qualified, поведение не определено.Могут быть несколько других; Загрузите черновик стандарта и выполните поиск «register», если вам интересно.
Как следует из названия, значение оригинала для
register
должно было требовать от объекта храниться в регистре CPU. Но с улучшением оптимизации компиляторов это стало менее полезным. Современные версии стандарта C не относятся к регистрам CPU, потому что они больше не нуждаются (должны) предполагать, что есть такая вещь (существуют архитектуры, которые не используют регистры). Общая мудрость заключается в том, что применениеregister
к объявлению объекта с большей вероятностью ухудшает сгенерированный код, потому что это мешает распределению собственного регистра компилятора. Там может быть несколько случаев, когда это полезно (скажем, если вы действительно знаете, как часто переменная будет доступна, и ваши знания лучше, чем то, что может вычислить современный оптимизирующий компилятор).основным ощутимым эффектом
register
является то, что он предотвращает любую попытку принять адрес объекта. Это не особенно полезно в качестве подсказки оптимизации, поскольку его можно применять только к локальным переменным, а оптимизационный компилятор может убедиться в том, что адрес такого объекта не принят.
Это на самом деле ожидаемое поведение. Из руководства :
Без GROUP BY существует одна группа, и недетерминировано, какое значение [неагрегированный столбец] выбрать для группы.
blockquote>Хотя это не очень четко указано, это означает, что вы всегда получаете одну группу (то есть одну строку), даже для пустой таблицы.
Также стоит подчеркнуть, что значения, которые MySQL выбирает для неагрегированных столбцов в ваших
select
,r.ID
иr.ReservationDate
, на самом деле являются недетерминированными и будут конкретно различаться в разных версиях MySQL (например, они обычно бытьnull
для MySQL 8.0, в то время как они обычно будут содержать существующие значения для более ранних версий).Решение аналогично тонкое - добавьте
group by
(чтобы цитируемое предложение больше не применяется):... where r.ConfirmationNumber = '123456' and p.CCLast4 = 'xxx' and r.ID = 54321 group by r.ID, r.ReservationDate
должно дать вам 0 строк.