ฉันสามารถสมมติ (bool) true == (int) 1 สำหรับคอมไพเลอร์ C ++ ได้หรือไม่


118

ฉันสามารถสมมติ(bool)true == (int)1สำหรับคอมไพเลอร์ C ++ ใด ๆ ได้หรือไม่


3
คำถามในคำถามของคุณซ้ำซ้อนควรย้อนกลับหรือไม่
GManNickG

9
เขาไม่ได้หมายความว่าพวกเขาจะถูกทิ้งเขาหมายถึงbool t = true; int n = 1; if (t == n) {...} ;
เช่นกูรูนิน

7
@egrunin: เอ๊ะ แต่ความจริงก็คือบูลและ 1 ก็คือ int อยู่ดี :)
GManNickG

1
ถูกต้องฉันตั้งใจจะระบุประเภทของค่าต่างๆ
Petruza

2
(int) trueคือ1เป็นค่าจำนวนเต็ม แต่สิ่งที่ผ่านไปส่วนหนึ่งแล้วถ้าif (pointer) pointer != 0สิ่งเดียวที่คุณสามารถสรุปได้ว่าเป็นความจริงก็คือfalse == 0และtrue != 0(และtrueประเมินว่า1เมื่อส่งถึงint)
Luis Colorado

คำตอบ:


134

ใช่. การร่ายซ้ำซ้อน ในการแสดงออกของคุณ:

true == 1

ใช้การส่งเสริมการขายแบบอินทิกรัลและค่าบูลจะเลื่อนระดับเป็นintและโปรโมชั่นนี้ต้องให้ผล 1

อ้างอิง: 4.7 [Conv.integral] / 4: หากประเภทแหล่งที่มาคือbool... trueถูกแปลงเป็นประเภทเดียว


9
@Joshua: trueเป็นคำหลักที่กำหนดโดยภาษา ห้องสมุดไม่สามารถกำหนดใหม่ได้ #defines ไม่ได้รับอนุญาตให้กำหนดคำหลักใหม่
jalf

21
@jalf: # define ได้รับอนุญาตให้กำหนดคีย์เวิร์ดของระบบ ขั้นตอนก่อนการประมวลผลของการคอมไพล์ C เป็นแบบข้อความล้วนๆและไม่รู้อะไรเกี่ยวกับคีย์เวิร์ดหรือไวยากรณ์ C โดยทั่วไป อย่างไรก็ตามแน่นอนว่าเป็นความคิดที่ไม่ดีในการกำหนดคำหลักภาษาใหม่
Dale Hagglund

2
@jalf พวกเขาไม่? ดูgcc.gnu.org/onlinedocs/cpp/Macros.htmlและอย่างน้อยหนึ่งรายการใน International Obfuscated C Code Contest ซึ่งเคยถามว่า "When dowhile not take a while?" (คำตอบ: เมื่อต้องใช้สองพารามิเตอร์เนื่องจากรายการ#definedนั้นถึงprintf)
Ken Bloom

3
C99, §6.10.1 / 1 กล่าวว่า: "นิพจน์ที่ควบคุมการรวมตามเงื่อนไขจะต้องเป็นนิพจน์คงที่ของจำนวนเต็มยกเว้นว่า: จะต้องไม่มีการร่ายตัวระบุ (รวมถึงคำที่เหมือนกันกับคำหลัก) ถูกตีความตามที่อธิบายไว้ด้านล่างนี้" แม้ว่าจะไม่ได้ระบุว่าเป็นการอนุญาตโดยตรง แต่ก็พิจารณาอย่างชัดเจนถึงความเป็นไปได้ของมาโครที่ "เหมือนกันทุกประการ" กับคำหลัก
Jerry Coffin

2
โอ้และ #defines ได้รับอนุญาตให้กำหนดคำหลักใหม่ C ++ 1x ทำให้เกิดปัญหากับคำหลักใหม่มากเกินไปจนต้องลบข้อกำหนดนั้นออกไป
Joshua

18

คำตอบของ Charles Bailey ถูกต้อง คำที่ถูกต้องจากมาตรฐาน C ++ คือ (§4.7 / 4): "ถ้าประเภทแหล่งที่มาคือบูลค่าเท็จจะถูกแปลงเป็นศูนย์และค่าจริงจะถูกแปลงเป็นค่าเดียว"

แก้ไข: ฉันเห็นว่าเขาเพิ่มข้อมูลอ้างอิงด้วย - ฉันจะลบสิ่งนี้ในไม่ช้าถ้าฉันไม่ฟุ้งซ่านและลืม ...

Edit2: จากนั้นอีกครั้งเป็นที่น่าสังเกตว่าแม้ว่าค่าบูลีนจะแปลงเป็นศูนย์หรือหนึ่งเสมอฟังก์ชันจำนวนหนึ่ง (โดยเฉพาะจากไลบรารีมาตรฐาน C) จะส่งคืนค่าที่เป็น "บูลีนโดยพื้นฐาน" แต่แสดงเป็นints ที่เป็น โดยปกติจะต้องเป็นศูนย์เท่านั้นเพื่อระบุเท็จหรือไม่ใช่ศูนย์เพื่อระบุว่าเป็นจริง ตัวอย่างเช่นฟังก์ชัน is * <ctype.h>ต้องการเพียงศูนย์หรือไม่ใช่ศูนย์ไม่จำเป็นต้องเป็นศูนย์หรืออย่างเดียว

หากคุณแคสboolต์เป็นศูนย์จะแปลงเป็นเท็จและไม่ใช่ศูนย์เป็นจริง (ตามที่คุณคาดหวัง)


9

ตามมาตรฐานคุณควรปลอดภัยกับสมมติฐานนั้น boolประเภทC ++ มีสองค่า - trueและfalseมีค่าที่สอดคล้องกัน 1 และ 0

สิ่งที่ต้องระวังคือการผสมboolนิพจน์และตัวแปรด้วยBOOLนิพจน์และตัวแปร หลังถูกกำหนดให้เป็นFALSE = 0และTRUE != FALSEซึ่งค่อนข้างบ่อยในวิธีการปฏิบัติที่แตกต่างจากค่า 0 ใด ๆ TRUEถือว่า

คอมไพเลอร์สมัยใหม่จำนวนมากจะออกคำเตือนสำหรับโค้ดใด ๆ ที่พยายามส่งโดยปริยายจากBOOLถึงboolหากBOOLค่าแตกต่างจาก 0 หรือ 1


3

ฉันพบว่าคอมไพเลอร์ต่างกันให้ผลลัพธ์ที่แตกต่างกันใน true ฉันยังพบว่าสิ่งหนึ่งมักจะดีกว่าเมื่อเปรียบเทียบบูลกับบูลแทนที่จะเป็น int int เหล่านั้นมีแนวโน้มที่จะเปลี่ยนค่าเมื่อเวลาผ่านไปเมื่อโปรแกรมของคุณพัฒนาขึ้นและหากคุณคิดว่าเป็นจริงเป็น 1 คุณอาจถูกกัดโดยการเปลี่ยนแปลงที่ไม่เกี่ยวข้องที่อื่นในโค้ดของคุณ


3
นี่เป็นคำตอบที่ไม่ถูกต้องสำหรับ C ++ เช่นเดียวtrueกับคำหลักภาษาที่มีพฤติกรรมที่กำหนดไว้ หากคุณอ้างถึงมาโครที่กำหนดโดยทั่วไปเช่นTRUEมันถูกต้อง
David Thornley

1
อาจเป็นประสบการณ์ของฉันกับคอมไพเลอร์ C ฉันใช้เวลามากมายกับพวกเขาในช่วงหลายปีที่ผ่านมา ประเด็นของฉันเกี่ยวกับการใช้นิพจน์ทางคณิตศาสตร์โดยตรงในกรณีที่คำสั่งยืนอยู่ เรามีโค้ดที่ดูว่าการเลื่อนบิตไม่ใช่ศูนย์ใน if หรือไม่แล้วมีคนอื่นรับค่าที่ไม่ใช่ศูนย์เดียวกันนั้นและคิดว่ามันเป็น 1 และระเบิดขึ้น การแปลงอย่างง่ายเป็นจริง / 1 จะป้องกันสิ่งนั้นได้
Michael Dorgan

ฉันก็เคยเห็นพฤติกรรมแบบนี้เช่นกัน เป็นที่ยอมรับครั้งสุดท้ายที่ฉันเห็นเมื่อประมาณปี 2542 ฉันใช้ GCC ภาษาเป็นภาษาซี แต่ฉันได้เห็นพฤติกรรมดังกล่าวแล้ว
บาท
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.