Nihai sonuç: a üzerindeki aritmetik hem C hem de C ++ ' void*
da yasa dışıdır .
GCC buna bir uzantı olarak izin verir, bkz. Aritmetik açık void
- ve İşlev İşaretçileri (bu bölümün kılavuzun "C Uzantıları" bölümünün bir parçası olduğunu unutmayın). Clang ve ICC muhtemelen void*
GCC ile uyumluluk amacıyla aritmetiğe izin verir . Diğer derleyiciler (MSVC gibi) aritmetiği açmaya izin vermez void*
ve GCC, -pedantic-errors
bayrak belirtilirse veya bayrak belirtilirse buna izin vermez -Werror-pointer-arith
(kod tabanınızın da MSVC ile derlenmesi gerekiyorsa bu bayrak yararlıdır).
C Standardı Konuşuyor
Alıntılar n1256 taslağından alınmıştır.
Standardın toplama işlemi ile ilgili açıklaması:
6.5.6-2: Ekleme için, her iki işlenen de aritmetik tipte olmalı ya da bir işlenen bir nesne tipine işaretçi ve diğeri de tamsayı tipinde olmalıdır.
Dolayısıyla, buradaki soru void*
, bir "nesne tipine" işaretçi mi , yoksa eşdeğer olarak void
"nesne tipine" mi ait olduğudur. "Nesne türü" tanımı:
6.2.5.1: Türler, nesne türlerine (nesneleri tam olarak açıklayan türler), işlev türlerine (işlevleri açıklayan türlere) ve eksik türlere (nesneleri tanımlayan ancak boyutlarını belirlemek için gereken bilgiye sahip olmayan türler ) bölünmüştür .
Ve standart şu void
şekilde tanımlar :
6.2.5-19: void
Tür boş bir değer kümesi içerir; tamamlanamayan eksik bir tür.
Yana void
tamamlanmamış bir türüdür, bir nesne türü değil. Bu nedenle, toplama işlemi için geçerli bir işlenen değildir.
Bu nedenle, bir void
işaretçide işaretçi aritmetiği gerçekleştiremezsiniz .
notlar
Başlangıçta, void*
C standardının bu bölümleri nedeniyle aritmetiğe izin verildiği düşünülüyordu :
6.2.5-27: Geçersiz
bir işaretçi, bir karakter türüne işaretçi ile aynı temsil ve hizalama gereksinimlerine sahip olmalıdır.
Ancak,
Aynı temsil ve hizalama
gereklilikleri, işlevlere argümanlar, işlevlerden değer döndürme ve sendika üyeleri olarak değiştirilebilirlik anlamına gelir.
Bu yollarla Yani printf("%s", x)
bakılmaksızın aynı anlama sahiptir x
türü vardır char*
ya void*
, ama bir aritmetik yapabileceği anlamına gelmez void*
.
Editörün notu: Bu cevap nihai sonucu yansıtacak şekilde düzenlendi.