จะกำหนดไฟล์ส่วนหัวที่จะรวมได้อย่างไร?


13

สมมติว่าฉันมีรหัสด้านล่าง (ง่ายมาก)

#include <iostream>
int main() {
    std::cout << std::stoi("12");
}

สิ่งนี้รวบรวมได้ดีทั้ง g ++ และ clang; อย่างไรก็ตามมันไม่สามารถคอมไพล์บน MSVC ด้วยข้อผิดพลาดต่อไปนี้:

ข้อผิดพลาด C2039: 'stoi': ไม่ใช่สมาชิกของ 'std'

ข้อผิดพลาด C3861: 'stoi': ไม่พบตัวระบุ

ฉันรู้ว่าstd::stoiมันเป็นส่วนหนึ่งของ<string>ส่วนหัวซึ่งน่าจะเป็นสิ่งที่คอมไพเลอร์อดีตสองคนรวมอยู่ในส่วนของ<iostream>และส่วนหลังไม่ได้ ตามมาตรฐาน C ++ [res.on.headers]

ส่วนหัว C ++ อาจรวมส่วนหัว C ++ อื่น ๆ

ซึ่งสำหรับฉันแล้วโดยทั่วไปบอกว่าคอมไพเลอร์ทั้งสามนั้นถูกต้อง

ปัญหานี้เกิดขึ้นเมื่อนักเรียนคนหนึ่งของฉันส่งงานซึ่ง TA ทำเครื่องหมายว่าไม่รวบรวม ฉันไปแล้วแน่นอน อย่างไรก็ตามฉันต้องการป้องกันเหตุการณ์ในอนาคตเช่นนี้ ดังนั้นมีวิธีการตรวจสอบไฟล์ส่วนหัวที่ควรจะรวมถึงการรวบรวมในสามคอมไพเลอร์ที่แตกต่างกันเพื่อตรวจสอบทุกครั้งหรือไม่

วิธีเดียวที่ฉันคิดได้ก็คือเพื่อให้แน่ใจว่าสำหรับstdการเรียกใช้ฟังก์ชันทุกครั้งจะมีการรวมที่เหมาะสม แต่ถ้าคุณมีรหัสที่มีอยู่ซึ่งมีความยาวหลายพันบรรทัดการค้นหาอาจน่าเบื่อ มีวิธีที่ง่ายกว่า / ดีกว่าในการตรวจสอบความเข้ากันได้ระหว่างคอมไพเลอร์หรือไม่?

ตัวอย่างกับคอมไพเลอร์สามตัว: https://godbolt.org/z/kJhS6U


6
หากคุณจำได้ว่าstd::stoiสำหรับการจัดการสตริงคุณสามารถเดาได้ว่า<string>จะเป็นส่วนหัวที่ดีในการ หรือคุณสามารถค้นหาการอ้างอิงที่ดีซึ่งจะบอกคุณ และฉันขอแนะนำให้คุณรวมไฟล์ส่วนหัวไว้อย่างชัดเจนเสมอดังนั้นคุณไม่จำเป็นต้องพึ่งพาพฤติกรรมการใช้งานที่ไม่พกพาได้
โปรแกรมเมอร์บางคนเพื่อน

3
วิธีที่ดีที่สุดคือไปที่cppreferenceก่อนไปที่แพลตฟอร์มอื่น พวกเขามีรายละเอียดค่อนข้างสวย
Siddharth

1
รวมส่วนหัวที่เหมาะสมในขณะที่คุณเขียนรหัส กล่าวคือ ทันทีที่คุณเขียนโค้ดที่มีstd::stoiคุณจะต้องแน่ใจว่า#include <string>มีอยู่ทันที
Sander De Dycker

3
ในกรณีทั่วไปนี้เป็นปัญหาที่ยาก อย่างไรก็ตามเมื่อเรากำลังพูดถึงไลบรารีมาตรฐานที่ขาดหายไปวิธีปกติก็คือการตรวจสอบการเรียกใช้ / ประเภทฟังก์ชั่นทั้งหมดที่ใช้
Max Langhof

1
@ skratchi.at นักเรียนบอกว่าพวกเขาสามารถใช้คอมไพเลอร์ใดก็ได้ที่พวกเขาต้องการตราบใดที่รหัสของพวกเขาสอดคล้องกับมาตรฐาน หลังจาก 4 ปีนี่เป็นครั้งแรกที่มีปัญหา
ChrisMM

คำตอบ:


14

มีวิธีที่ง่ายกว่าหรือดีกว่าในการตรวจสอบความเข้ากันได้ระหว่างคอมไพเลอร์?

นี่จะเป็นเรื่องที่น่าเบื่ออยู่เสมอหากคุณมี codebase ขนาดใหญ่และยังไม่ได้ทำสิ่งนี้มาก่อน แต่เมื่อคุณได้แก้ไขการรวมของคุณแล้วคุณสามารถทำตามขั้นตอนง่าย ๆ :

เมื่อคุณเขียนรหัสใหม่ที่ใช้คุณสมบัติมาตรฐานเช่นstd::stoiเสียบชื่อนั้นลงใน Google ไปที่บทความ cppreference.com สำหรับมันจากนั้นดูที่ด้านบนเพื่อดูว่าส่วนหัวที่กำหนดไว้

จากนั้นรวมถึงหากยังไม่ได้รวม งานเสร็จแล้ว!

(คุณสามารถใช้มาตรฐานนี้ แต่ไม่สามารถเข้าถึงได้)

อย่าถูกล่อลวงไปปลดมันออกทั้งหมดในความโปรดปรานของราคาถูกแฮ็ก unportableชอบ<bits/stdc++.h>!


tl; dr: เอกสาร


3
เพื่อความเป็นธรรมเมื่อคุณจดจำพวกเขาทั้งหมดได้อย่างมีประสิทธิภาพและไม่จำเป็นต้องค้นหามันอีกต่อไปนั่นจะทำให้คุณรู้สึกเนียนสวย
Lightness Races ใน Orbit

5
@JosephWood: หากคุณไม่ทราบว่าส่วนหัวของฟังก์ชั่นที่กำหนดคืออะไรโดยการท่องจำโอกาสที่คุณควรตรวจสอบฟังก์ชั่นของคุณเพื่อตรวจสอบสมมติฐานของคุณซ้ำอีกครั้ง เวลา.
DevSolar

1
เช่นเดียวกับ @JosephWood ฉันก็หวังว่าผู้ที่มีประสบการณ์มากกว่าจะมีวิธีที่ดีกว่า ฉันรู้ว่าส่วนหัวใดที่จะรวมไว้ในฟังก์ชั่น STL ส่วนใหญ่ แต่หวังว่าจะมีวิธีสอนนักเรียนได้ง่ายกว่าการค้นหาทุกฟังก์ชั่น: P
ChrisMM

1
@ChrisMM มีเครื่องมือชอบรวมถึงสิ่งที่คุณใช้งาน ไม่สามารถรับประกันความถูกต้องของพวกเขา (และบางครั้งจำเป็นต้องทำงานด้วยตนเอง) แต่ก็ไม่เลวเลย
ประหลาด

4
@ChrisMM การเรียนการสอนของนักเรียนในการอ้างถึงเอกสารเป็นอย่างเหลือเชื่อสำคัญอย่างเหลือเชื่อ สตรีมนับพันเข้าสู่เว็บไซต์นี้ทุกวันโดยไม่มีความคิดทางโลกว่าพวกเขาควรทำ การใช้เอกสารเป็นวิธีที่ง่ายกว่า / ดีกว่า
Lightness Races ใน Orbit

-1

นอกเหนือจากการตรวจสอบเอกสารและการทำด้วยตนเอง (เจ็บปวดและเสียเวลา) คุณสามารถใช้เครื่องมือบางอย่างที่สามารถทำเพื่อคุณได้

คุณสามารถใช้ ReSharper ใน Visual Studio ซึ่งสามารถจัดการการนำเข้า (ในความเป็นจริง VS โดยไม่มี ReSharper นั้นใช้ไม่ได้มาก) หากไม่มีการรวมไว้ขอแนะนำให้เพิ่มและหากเป็นสายที่ล้าสมัยด้วยการรวมจะปรากฏในสีซีดมากขึ้น

หรือคุณสามารถใช้ CLion (ใช้ได้กับทุกแพลตฟอร์ม) ซึ่งมีความสามารถเช่นนี้ (อันที่จริงแล้วเป็น JetBrains ที่ใช้งานได้เหมือนกัน)

นอกจากนี้ยังมีเครื่องมือที่เรียกว่ารวมถึงสิ่งที่คุณใช้แต่เป้าหมายของมันคือการใช้ประโยชน์จากการประกาศล่วงหน้าฉันไม่เคยใช้มันเลย (โดยส่วนตัว - เพื่อนร่วมทีมของฉันทำสิ่งนั้นสำหรับโครงการของเรา)


clion ไม่รวมส่วนหัวที่ถูกต้องโดยอัตโนมัติเมื่อรวมส่วนหัวอื่นแล้วหากงาน (เช่นจะไม่แนะนำสตริงที่นี่หากรวม iostream ไว้แล้ว) IIRC
RiaD
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.