Остаточний висновок: арифметика на a void*є незаконною як для C, так і для C ++.
GCC дозволяє це як розширення, див. Арифметичні вказівки void- та функціональні покажчики (зверніть увагу, що цей розділ є частиною розділу "Розширення C" цього посібника). Clang та ICC, ймовірно, дозволяють void*арифметикувати для сумісності з GCC. Інші компілятори (наприклад, MSVC) забороняють вмикати арифметику void*, а GCC забороняє її, якщо -pedantic-errorsвказано прапор або якщо -Werror-pointer-arithвказано прапор (цей прапор корисний, якщо ваша база коду також повинна компілюватися з MSVC).
Стандарт C говорить
Цитати взяті з чернетки n1256.
В описі стандарту операції додавання зазначено:
6.5.6-2: Крім того, або обидва операнди мають арифметичний тип, або один операнд є вказівником на тип об'єкта, а інший має цілий тип.
Отже, тут питання void*полягає в тому, чи є вказівник на "тип об'єкта", або рівнозначно, чи void"тип об'єкта". Визначенням "тип об'єкта" є:
6.2.5.1: Типи поділяються на типи об'єктів (типи, що повністю описують об'єкти), типи функцій (типи, що описують функції), і неповні типи (типи, що описують об'єкти, але не мають інформації, необхідної для визначення їх розмірів).
А стандарт визначає voidяк:
6.2.5-19: voidТип містить порожній набір значень; це незавершений тип, який неможливо виконати.
Оскільки voidце незавершений тип, це не тип об'єкта. Тому це не є дійсним операндом операції додавання.
Тому ви не можете виконувати арифметику вказівника на voidпокажчику.
Примітки
Спочатку вважалося, що void*арифметика дозволена через такі розділи стандарту С:
6.2.5-27: Вказівник на недійсність повинен мати ті ж
вимоги щодо представлення та вирівнювання , що і вказівник на тип символів.
Однак,
Ті ж
вимоги щодо представлення та вирівнювання мають на увазі взаємозамінність як аргументи до функцій, повернення значень функцій та членів союзів.
Отже, це означає, що printf("%s", x)має те саме значення, чи xмає тип char*або void*, але це не означає, що ви можете робити арифметику на a void*.
Примітка редактора: Ця відповідь була відредагована для відображення остаточного висновку.