C++ - Jag Förstår Inte Detta Fel

Permalänk
Medlem

C++ - Jag Förstår Inte Detta Fel

Hej,

För ett tag sedan fick jag hjälp med att skriva ett program som skriver ut max och min för numeriska typer. Jag får ett stort antal fel som jag inte riktigt fattar. Nedan är koden:

#include <limits> #include <cstddef> #include <string> #include <bit> #include <type_traits> #include <sstream> #include <iostream> template <typename T> requires std::is_signed_v <T> std::string to_power_of_two(T val) { const bool negative = val < 0; using U = std::make_unsigned_t <T>; const U uval = negative ? static_cast <U> (- val) : static_cast <U> (val); const auto width = std::bit_width(uval) - negative; std::ostringstream ss; ss << (negative ? '-' : '+') << "2^" << width; if (! negative) { ss << "-1"; } return ss.str (); } template <typename T> requires std::is_unsigned_v <T> std::string to_power_of_two(T val) { std::ostringstream ss; ss << "+2^" << std::bit_width(val) << "-1"; return ss.str (); } template <typename T> void print(const std::string &name) { std::cout << "**** " << name << " ****" << std::endl; if constexpr (std::is_unsigned_v <T>) { std::cout << "Min: " << std::dec << std::numeric_limits<T>::min() << std::endl; } else { std::cout << "Min: " << std::dec << std::numeric_limits<T>::min() << " = " << to_power_of_two(std::numeric_limits<T>::min()) << std::endl; } std::cout << "Max: " << std::dec << std::numeric_limits<T>::max() << " = " << to_power_of_two(std::numeric_limits<T>::max()) << std::endl; } #define PRINT(x) print <x> (#x) int main() { std::cout << "Below is a list of max and min values for all numeric types on this system: " << '\n'; std::cout << "*********** Integer Ranges ************" << '\n'; PRINT(short int); std::cout << '\n'; PRINT(unsigned short int); std::cout << '\n'; PRINT(int); std::cout << '\n'; PRINT(unsigned int); std::cout << '\n'; PRINT(long int); std::cout << '\n'; PRINT(unsigned long int); std::cout << '\n'; PRINT(long long int); std::cout << '\n'; PRINT(unsigned long long int); std::cout << '\n'; PRINT(int16_t); std::cout << '\n'; PRINT(int32_t); std::cout << '\n'; PRINT(int64_t); std::cout << '\n'; PRINT(uint16_t); std::cout << '\n'; PRINT(uint32_t); std::cout << '\n'; PRINT(uint64_t); std::cout << '\n'; std::cout << "*********** Floating Point Ranges ************" << '\n'; std::cout << "**** float ****" << '\n'; std::cout << "Min (±): " << std::dec << std::numeric_limits<float>::min() << '\n'; std::cout << "Max (±): " << std::dec << std::numeric_limits<float>::max() << '\n'; std::cout << '\n'; std::cout << "**** double ****" << '\n'; std::cout << "Min (±): " << std::dec << std::numeric_limits<double>::min() << '\n'; std::cout << "Max (±): " << std::dec << std::numeric_limits<double>::max() << '\n'; std::cout << '\n'; std::cout << "**** long double ****" << '\n'; std::cout << "Min (±): " << std::dec << std::numeric_limits<long double>::min() << '\n'; std::cout << "Max (±): " << std::dec << std::numeric_limits<long double>::max() << '\n'; return 0; }

Och felen som VS Code ger mig (sorry att det är långt...):

[{ "resource": "/mnt/Storage_SSD/C++_Projects/value_limits/value_limits.cpp", "owner": "C/C++1", "code": "77", "severity": 8, "message": "this declaration has no storage class or type specifier", "source": "C/C++", "startLineNumber": 10, "startColumn": 1, "endLineNumber": 10, "endColumn": 9 },{ "resource": "/mnt/Storage_SSD/C++_Projects/value_limits/value_limits.cpp", "owner": "C/C++1", "code": "65", "severity": 8, "message": "expected a ';'", "source": "C/C++", "startLineNumber": 10, "startColumn": 10, "endLineNumber": 10, "endColumn": 30 },{ "resource": "/mnt/Storage_SSD/C++_Projects/value_limits/value_limits.cpp", "owner": "C/C++1", "code": "77", "severity": 8, "message": "this declaration has no storage class or type specifier", "source": "C/C++", "startLineNumber": 70, "startColumn": 5, "endLineNumber": 70, "endColumn": 8 },{ "resource": "/mnt/Storage_SSD/C++_Projects/value_limits/value_limits.cpp", "owner": "C/C++1", "code": "65", "severity": 8, "message": "expected a ';'", "source": "C/C++", "startLineNumber": 70, "startColumn": 15, "endLineNumber": 70, "endColumn": 17 },{ "resource": "/mnt/Storage_SSD/C++_Projects/value_limits/value_limits.cpp", "owner": "C/C++1", "code": "77", "severity": 8, "message": "this declaration has no storage class or type specifier", "source": "C/C++", "startLineNumber": 71, "startColumn": 5, "endLineNumber": 71, "endColumn": 8 },{ "resource": "/mnt/Storage_SSD/C++_Projects/value_limits/value_limits.cpp", "owner": "C/C++1", "code": "65", "severity": 8, "message": "expected a ';'", "source": "C/C++", "startLineNumber": 71, "startColumn": 15, "endLineNumber": 71, "endColumn": 17 },{ "resource": "/mnt/Storage_SSD/C++_Projects/value_limits/value_limits.cpp", "owner": "C/C++1", "code": "77", "severity": 8, "message": "this declaration has no storage class or type specifier", "source": "C/C++", "startLineNumber": 72, "startColumn": 5, "endLineNumber": 72, "endColumn": 8 },{ "resource": "/mnt/Storage_SSD/C++_Projects/value_limits/value_limits.cpp", "owner": "C/C++1", "code": "65", "severity": 8, "message": "expected a ';'", "source": "C/C++", "startLineNumber": 72, "startColumn": 15, "endLineNumber": 72, "endColumn": 17 },{ "resource": "/mnt/Storage_SSD/C++_Projects/value_limits/value_limits.cpp", "owner": "C/C++1", "code": "77", "severity": 8, "message": "this declaration has no storage class or type specifier", "source": "C/C++", "startLineNumber": 74, "startColumn": 5, "endLineNumber": 74, "endColumn": 8 },{ "resource": "/mnt/Storage_SSD/C++_Projects/value_limits/value_limits.cpp", "owner": "C/C++1", "code": "65", "severity": 8, "message": "expected a ';'", "source": "C/C++", "startLineNumber": 74, "startColumn": 15, "endLineNumber": 74, "endColumn": 17 },{ "resource": "/mnt/Storage_SSD/C++_Projects/value_limits/value_limits.cpp", "owner": "C/C++1", "code": "77", "severity": 8, "message": "this declaration has no storage class or type specifier", "source": "C/C++", "startLineNumber": 76, "startColumn": 5, "endLineNumber": 76, "endColumn": 8 },{ "resource": "/mnt/Storage_SSD/C++_Projects/value_limits/value_limits.cpp", "owner": "C/C++1", "code": "65", "severity": 8, "message": "expected a ';'", "source": "C/C++", "startLineNumber": 76, "startColumn": 15, "endLineNumber": 76, "endColumn": 17 },{ "resource": "/mnt/Storage_SSD/C++_Projects/value_limits/value_limits.cpp", "owner": "C/C++1", "code": "77", "severity": 8, "message": "this declaration has no storage class or type specifier", "source": "C/C++", "startLineNumber": 77, "startColumn": 5, "endLineNumber": 77, "endColumn": 8 },{ "resource": "/mnt/Storage_SSD/C++_Projects/value_limits/value_limits.cpp", "owner": "C/C++1", "code": "65", "severity": 8, "message": "expected a ';'", "source": "C/C++", "startLineNumber": 77, "startColumn": 15, "endLineNumber": 77, "endColumn": 17 },{ "resource": "/mnt/Storage_SSD/C++_Projects/value_limits/value_limits.cpp", "owner": "C/C++1", "code": "77", "severity": 8, "message": "this declaration has no storage class or type specifier", "source": "C/C++", "startLineNumber": 78, "startColumn": 5, "endLineNumber": 78, "endColumn": 8 },{ "resource": "/mnt/Storage_SSD/C++_Projects/value_limits/value_limits.cpp", "owner": "C/C++1", "code": "65", "severity": 8, "message": "expected a ';'", "source": "C/C++", "startLineNumber": 78, "startColumn": 15, "endLineNumber": 78, "endColumn": 17 },{ "resource": "/mnt/Storage_SSD/C++_Projects/value_limits/value_limits.cpp", "owner": "C/C++1", "code": "77", "severity": 8, "message": "this declaration has no storage class or type specifier", "source": "C/C++", "startLineNumber": 80, "startColumn": 5, "endLineNumber": 80, "endColumn": 8 },{ "resource": "/mnt/Storage_SSD/C++_Projects/value_limits/value_limits.cpp", "owner": "C/C++1", "code": "65", "severity": 8, "message": "expected a ';'", "source": "C/C++", "startLineNumber": 80, "startColumn": 15, "endLineNumber": 80, "endColumn": 17 },{ "resource": "/mnt/Storage_SSD/C++_Projects/value_limits/value_limits.cpp", "owner": "C/C++1", "code": "77", "severity": 8, "message": "this declaration has no storage class or type specifier", "source": "C/C++", "startLineNumber": 82, "startColumn": 5, "endLineNumber": 82, "endColumn": 8 },{ "resource": "/mnt/Storage_SSD/C++_Projects/value_limits/value_limits.cpp", "owner": "C/C++1", "code": "65", "severity": 8, "message": "expected a ';'", "source": "C/C++", "startLineNumber": 82, "startColumn": 15, "endLineNumber": 82, "endColumn": 17 },{ "resource": "/mnt/Storage_SSD/C++_Projects/value_limits/value_limits.cpp", "owner": "C/C++1", "code": "77", "severity": 8, "message": "this declaration has no storage class or type specifier", "source": "C/C++", "startLineNumber": 83, "startColumn": 5, "endLineNumber": 83, "endColumn": 8 },{ "resource": "/mnt/Storage_SSD/C++_Projects/value_limits/value_limits.cpp", "owner": "C/C++1", "code": "65", "severity": 8, "message": "expected a ';'", "source": "C/C++", "startLineNumber": 83, "startColumn": 15, "endLineNumber": 83, "endColumn": 17 },{ "resource": "/mnt/Storage_SSD/C++_Projects/value_limits/value_limits.cpp", "owner": "C/C++1", "code": "77", "severity": 8, "message": "this declaration has no storage class or type specifier", "source": "C/C++", "startLineNumber": 84, "startColumn": 5, "endLineNumber": 84, "endColumn": 8 },{ "resource": "/mnt/Storage_SSD/C++_Projects/value_limits/value_limits.cpp", "owner": "C/C++1", "code": "65", "severity": 8, "message": "expected a ';'", "source": "C/C++", "startLineNumber": 84, "startColumn": 15, "endLineNumber": 84, "endColumn": 17 },{ "resource": "/mnt/Storage_SSD/C++_Projects/value_limits/value_limits.cpp", "owner": "C/C++1", "code": "169", "severity": 8, "message": "expected a declaration", "source": "C/C++", "startLineNumber": 86, "startColumn": 5, "endLineNumber": 86, "endColumn": 11 },{ "resource": "/mnt/Storage_SSD/C++_Projects/value_limits/value_limits.cpp", "owner": "C/C++1", "code": "169", "severity": 8, "message": "expected a declaration", "source": "C/C++", "startLineNumber": 87, "startColumn": 1, "endLineNumber": 87, "endColumn": 2 }]

Det konstiga är att allt går bra om jag lägger till detta i projektmappen i ".vscode/settings.json":

{ "C_Cpp.errorSquiggles": "disabled" }

och kör detta kompileringskommando:

g++ -std=c++20 -Wall value_limits.cpp -o value_limits

Vad är felet och hur kan jag åtgärda det? Jag kör på Ubuntu 22.04 LTS.

Permalänk
Medlem

Felet verkar vara att koden t.ex. använder requires vilket är nytt i C++20, så det fungerar med g++ när du manuellt anger att du vill använda C++20. Så troligtvis behöver du ställa in VS Code på att använda samma flagga på något sätt, standard i nyare version av GCC är annars C++17.

Permalänk
Medlem
Skrivet av perost:

Felet verkar vara att koden t.ex. använder requires vilket är nytt i C++20, så det fungerar med g++ när du manuellt anger att du vill använda C++20. Så troligtvis behöver du ställa in VS Code på att använda samma flagga på något sätt, standard i nyare version av GCC är annars C++17.

Får dessa fel när jag kör använder make (mycket text igen):

alexl@PD70PNP:/mnt/Storage_SSD/C++_Projects/value_limits$ make g++ -std=c++20 -Wall -o value_limits obj/main.o obj/poweroftwo.o /usr/bin/ld: obj/main.o: in function `void print<short>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)': main.cpp:(.text._Z5printIsEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE[_Z5printIsEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE]+0xdd): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > to_power_of_two<short>(short)' /usr/bin/ld: main.cpp:(.text._Z5printIsEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE[_Z5printIsEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE]+0x179): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > to_power_of_two<short>(short)' /usr/bin/ld: obj/main.o: in function `void print<unsigned short>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)': main.cpp:(.text._Z5printItEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE[_Z5printItEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE]+0x134): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > to_power_of_two<unsigned short>(unsigned short)' /usr/bin/ld: obj/main.o: in function `void print<int>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)': main.cpp:(.text._Z5printIiEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE[_Z5printIiEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE]+0xdb): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > to_power_of_two<int>(int)' /usr/bin/ld: main.cpp:(.text._Z5printIiEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE[_Z5printIiEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE]+0x175): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > to_power_of_two<int>(int)' /usr/bin/ld: obj/main.o: in function `void print<unsigned int>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)': main.cpp:(.text._Z5printIjEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE[_Z5printIjEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE]+0x12d): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > to_power_of_two<unsigned int>(unsigned int)' /usr/bin/ld: obj/main.o: in function `void print<long>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)': main.cpp:(.text._Z5printIlEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE[_Z5printIlEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE]+0xde): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > to_power_of_two<long>(long)' /usr/bin/ld: main.cpp:(.text._Z5printIlEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE[_Z5printIlEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE]+0x17b): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > to_power_of_two<long>(long)' /usr/bin/ld: obj/main.o: in function `void print<unsigned long>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)': main.cpp:(.text._Z5printImEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE[_Z5printImEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE]+0x131): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > to_power_of_two<unsigned long>(unsigned long)' /usr/bin/ld: obj/main.o: in function `void print<long long>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)': main.cpp:(.text._Z5printIxEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE[_Z5printIxEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE]+0xde): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > to_power_of_two<long long>(long long)' /usr/bin/ld: main.cpp:(.text._Z5printIxEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE[_Z5printIxEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE]+0x17b): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > to_power_of_two<long long>(long long)' /usr/bin/ld: obj/main.o: in function `void print<unsigned long long>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)': main.cpp:(.text._Z5printIyEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE[_Z5printIyEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE]+0x131): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > to_power_of_two<unsigned long long>(unsigned long long)' collect2: error: ld returned 1 exit status make: *** [Makefile:36: value_limits] Error 1

Permalänk
Medlem
Skrivet av Apollo11:

Får dessa fel när jag kör använder make (mycket text igen):

Där ser det ut som att du delat upp koden i två filer, eftersom du har två objektfiler (main.o, poweroftwo.o). Felen du får ser ut som att du försökt lägga to_power_of_two i sin egen .cpp-fil, men det fungerar inte eftersom den är en template-funktion.

Permalänk
Medlem
Skrivet av perost:

Där ser det ut som att du delat upp koden i två filer, eftersom du har två objektfiler (main.o, poweroftwo.o). Felen du får ser ut som att du försökt lägga to_power_of_two i sin egen .cpp-fil, men det fungerar inte eftersom den är en template-funktion.

Ok, tack! fixade det samt åtgärdade det där med vilken standard VS Code använder.

Output från make:

alexl@PD70PNP:/mnt/Storage_SSD/C++_Projects/value_limits$ make g++ -std=c++20 -Wall -o obj/main.o -c src/main.cpp g++ -std=c++20 -Wall -o value_limits obj/main.o