“False <true” işlemi iyi tanımlanmış mı?


153

C ++ belirtimi şunları tanımlıyor mu?

  1. boole parametreleri için 'küçüktür' operatörünün varlığı ve varsa,
  2. 4 parametre permütasyonunun sonucu nedir?

Başka bir deyişle, aşağıdaki işlemlerin sonuçları spesifikasyon tarafından tanımlanmış mı?

false < false
false < true
true < false
true < true

Kurulumumda (Centos 7, gcc 4.8.2), aşağıdaki kod beklediğimi ortaya koyuyor (C'nin false değerini 0 ve true olarak 1 olarak temsil etme geçmişi göz önüne alındığında):

false < false = false
false < true = true
true < false = false
true < true = false

Çoğu (tümü?) Derleyicinin aynı çıktıyı vereceğinden emin olmamıza rağmen, bu C ++ belirtimine uygun mu? Ya da şaşkın, ancak şartnameye uygun bir derleyicinin, doğrunun yanlıştan küçük olduğuna karar vermesine izin veriliyor mu?

#include <iostream>

const char * s(bool a)
{
  return (a ? "true" : "false");
}

void test(bool a, bool b)
{
  std::cout << s(a) << " < " << s(b) << " = " << s(a < b) << std::endl;
}

int main(int argc, char* argv[])
{
  test(false, false);
  test(false, true);
  test(true, false);
  test(true, true);
  return 0;
}

6
@Ulterior Geçerli kullanımlar var. Bu tür kullanılarak std::minilgili std::vector<bool>olarak &&.
Angew artık SO

19
@Unterior, tüm bu yıllar boyunca StackOverflow'dan sonra henüz sorulmamış iyi bir soru bulabilirseniz, bazı noktaları hak ediyorsunuz . Troll değil.
Mark Ransom

35
@Ulterior Sorma motivasyonu gerçek: C ++ (C'den geliyor) için oldukça yeniyim ve bazı nesneleri std :: set <> 'de saklamak istiyorum. Nesnemin <işlecini uygulamam, öncelikle nesnenin bir boole özelliğine, ardından da diğer ikincil tanımlama özelliklerine dayanır. Kümenin üzerinde yineleme yaparken, önce 'yanlış' nesnelerin geldiğinden emin olmak istiyorum. Burada ve şimdi benim için çalışıyor olsa da, nesnelerimde (a? 1: 0) veya benzerlerinin kullanımına gereksiz yere başvurmak zorunda kalmadan platformlar arasında (gömülü olanlar dahil) çalışacağı garanti ediliyor. Şebeke.
duncan

26
Rahatsız edici bir sonuç, ne zaman ve bool tipi olduğu p <= qanlamına gelir ! p implies qpq
Theodore Norvell

4
@Technophile Rahatsız edici olan şey, <=yanlışlıkla bir leftarrow olarak okunabilecek ve "yalnızca" (yani, "[maddi] ima ederse") rightarrow'un bazen benzer veya gayri resmi olarak yazılmasıdır =>(yani, iki kat şaft benzeyen =). . Bir leftarrow bazen "if" olarak okunur, ancak bunun "sadece" için bir rightarrow kullanımından çok daha az yaygın olduğuna inanıyorum.
Eliah Kagan

Yanıtlar:


207

TL; DR:

İşlemler taslak C ++ standardına göre iyi tanımlanmıştır.

ayrıntılar

Taslak C ++ standart bölümü 5.9 İlişkisel işleçlere gidip şunu söyleyebiliriz ( ileriye dönük maden ):

İşlenenler aritmetik sahip olacaktır , numaralandırma ya işaretçi türü veya tür std :: nullptr_t. <(Küçüktür),> (büyüktür), <= (küçüktür veya eşittir) ve> = (eşit veya büyüktür) işleçlerinin tümü yanlış veya doğru verir. Sonucun türü bool

ve booller 3.9.1'in temel aritmetik tipleridir.

Türleri bool , Kuruma, char16_t, char32_t, wchar_t ve imzalı ve imzasız tamsayı türleri topluca edilir ayrılmaz türlerini çağırdı.

ve

İntegral ve kayan tipler topluca aritmetik tipler olarak adlandırılır.

ve trueve falseBoole değişmezlerinden gelen boole 2.14.6değişmezleri:

boolean-literal:
    false
    true

5.9İlişkisel operatörlerin mekaniğini daha fazla görmek için bölüme dönersek , diyor ki:

Genel aritmetik dönüşümler, aritmetik veya numaralandırma türündeki işlenenlerde gerçekleştirilir.

Her zamanki aritmetik dönüşümler bölümünde kaplıdır 5diyor ki:

Aksi takdirde, integral tanıtımlar (4.5) her iki işlenende de gerçekleştirilecektir.

ve bölüm 4.5diyor ki:

Bool türünün bir ön değeri, int sıfır türüne ve yanlış olanın bir sıfıra dönüşmesine neden olabilir.

ve böylece ifadeler:

false < false
false < true
true < false
true < true

bu kuralları kullanmak:

0 < 0
0 < 1
1 < 0
1 < 1

6
Güzel, bu okunması kolay olsa da, herhangi bir cevabın olabileceği kadar açıktır. Bir nit: Sanırım yanlış "tip" kalın yazılmış: İşlenenler aritmetik , numaralandırma veya işaretçi türü veya std :: nullptr_t yazın. " Netlik için parantez eklenmesi ((aritmetik, numaralandırma veya işaretçi) türü) veya (std :: nullptr_t türü) verir.

Cevabınızı değiştirdiği için değil, ama N3485 [over.built] / 12: Her bir yükseltilmiş aritmetik tip L ve R çifti için, ... bool operatörü <(L, R) formunun aday operatör işlevleri vardır ; - Alıntı yaptığınız kurallar uygulanmadan önce öne sürülen argümanlar değil mi?
chris

@chris Bu bölüme çok aşina değilim, bu yüzden düşünmek zorunda kalacağım ama cevabın görebildiğimden değiştiğini düşünmüyorum.
Shafik Yaghmour

Evet, promosyon her iki şekilde de gerçekleşecek ilk şey.
chris

63

Boole değerleri, olarak falsetanımlanan 0ve olarak truetanımlanan olağan tamsayı tanıtımlarına tabidir 1. Bu, tüm karşılaştırmaları iyi tanımlanmış hale getirir.


2
... ve ilişkisel işleçler, aritmetik veya numaralandırma türündeki işlenenler üzerinde olağan aritmetik dönüşümleri (tamsayı yükseltmeleri içeren) gerçekleştirmek için belirtilir.
TC

5
Bu cevap Shafik en kısa olduğu gibi, ama anahtar noktayı düşünmek falseolarak tanımlanır 0ve trueolarak tanımlanır 1 standardında (yerine sadece yaygın bir uygulama tarafından değil) yedeklemek için kanıt gerekir.
KRyan

@KRyan ne, sözümü almayacak mısın? :) Bir booltür bulunmadan önce, C ++ olmadan önce, bir boole işleminin sonucu 0yanlış ve 1doğru olarak tanımlandı . K + R'de bulabilirseniz şaşırmam.
Mark Ransom

1
@KRyan K + R kadar ileri gidemem, ancak 1990 ANSI C Standardının kopyasını çıkardım. Bölüm 6.3.8 " Belirtilen ilişki doğruysa <(daha küçük), >(büyük), <=(küçük veya eşit) ve >=(büyük veya eşit büyük ) operatörlerin her biri , belirtilen ilişki doğruysa 1, eğer 0 ise false. Sonuçta tür var int. "
Mark Ransom

1
En büyük sorun IIRC K & R, olmasıydı enum bool { false = 0, true = 1}yasal ama bir tanımlama yoktu operator<.
MSalters

22

C ++ Standardına göre (5.9 İlişkisel operatörler)

2 Genel aritmetik dönüşümler, aritmetik veya numaralandırma tipi işlenenlerde gerçekleştirilir.

ve

1 ... Sonucun türü bool.

ve (3.9.1 Temel türler)

6 Bool tipi değerler doğru veya yanlıştır.49 [Not: İmzalı, imzasız, kısa veya uzun bool tipi veya değeri yoktur. —End not] Tip bool değerleri integral promosyonlarına katılır (4.5).

ve (4.5 İntegral tanıtımları)

6 Bool türü bir ön değer, int sıfır türüne ve yanlış bir sıfıra dönüşerek int türünde bir ön değere dönüştürülebilir .

Yani tüm örneklerinizde true, int 1'e ve false, int 0'a dönüştürülür

Bu ifadeler

false < false
false < true
true < false
true < true

tamamen eşdeğerdir

0 < 0
0 < 1
1 < 0
1 < 1

8

Boolean falseeşittir int 0ve boolean trueeşittir int 1. Bu, false < true=> ifadesinin neden 0 < 1geri dönen tek ifade olduğunu açıklar true.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.