diff --git a/Makefile b/Makefile index bd18f16..be89a08 100755 --- a/Makefile +++ b/Makefile @@ -1,39 +1,40 @@ - export BUILD_CMD=clang++ -Wall -std=c++17 -Wall -Wextra -O1 -g -fsanitize=address -fno-omit-frame-pointer +CC := clang++ -Wall -std=c++17 -Wall -Wextra -O1 -g -fsanitize=address,undefined -fno-omit-frame-pointer setup: mkdir build + chmod -R +x src/ sheet0: - ${BUILD_CMD} src/sheet00.cpp -o build/sheet0 + $(CC) src/sheet00.cpp -o build/sheet0 chmod +x build/sheet0 build/sheet0 sheet01: - ${BUILD_CMD} src/sheet01.cpp -o build/sheet01 + $(CC) src/sheet01.cpp -o build/sheet01 chmod +x build/sheet01 build/sheet01 sheet02: - ${BUILD_CMD} src/sheet02.cpp -o build/sheet02 + $(CC) src/sheet02.cpp -o build/sheet02 chmod +x build/sheet02 build/sheet02 sheet03: - ${BUILD_CMD} src/sheet03.cpp src/MyType.cpp -o build/sheet03 + $(CC) src/sheet03.cpp src/MyType.cpp -o build/sheet03 chmod +x build/sheet03 build/sheet03 sheet04: - ${BUILD_CMD} src/sheet04.cpp -o build/sheet04 + $(CC) src/sheet04.cpp -o build/sheet04 chmod +x build/sheet04 build/sheet04 -cint: - ${BUILD_CMD} src/cint.cpp -o build/cint - chmod +x build/cint - build/cint +sheet05: + $(CC) src/sheet05.cpp -o build/sheet05 + chmod +x build/sheet05 + build/sheet05 pizza: - ${BUILD_CMD} src/pizza.cpp -o build/pizza + $(CC) src/pizza.cpp -o build/pizza chmod +x build/pizza build/pizza diff --git a/src/MyType.cpp b/src/MyType.cpp old mode 100644 new mode 100755 diff --git a/src/cint.cpp b/src/cint.cpp old mode 100644 new mode 100755 index 349a3e3..c2e09a4 --- a/src/cint.cpp +++ b/src/cint.cpp @@ -15,7 +15,9 @@ #include #include -const int MIN_MAX_DIFF = std::abs(std::abs(std::numeric_limits::min())-std::abs(std::numeric_limits::max())); +constexpr int max = std::numeric_limits::max(); +constexpr int min = std::numeric_limits::min(); + class sint { private: int value; @@ -58,15 +60,23 @@ class sint { return result; } - // friend sint operator/(sint lhs, sint rhs) - // { - // int result; - // if(__builtin_sdiv_overflow(lhs.getUnderlyingValue(), rhs.getUnderlyingValue(), &result)) - // { - // throw std::overflow_error("division overflow"); - // } - // return result; - // } + friend sint operator/(sint lhs, sint rhs) + { + if(rhs.getUnderlyingValue()==0) + { + throw std::overflow_error("division by 0"); + } + + //If two's complement + constexpr bool twos = min != -max; + if(twos && lhs.getUnderlyingValue() == min && rhs.getUnderlyingValue() == -1) + { + throw std::overflow_error("division with integer maximum and -1"); + } + + return lhs.getUnderlyingValue()/rhs.getUnderlyingValue(); + } + sint &operator++() { *this = *this + 1; @@ -96,6 +106,9 @@ class sint { } }; +const sint smax = max; +const sint smin = min; + int main() { // You are of course free to extend these tests! @@ -106,8 +119,6 @@ int main() { std::cout << c << '\n'; // // setup some values - sint max = std::numeric_limits::max(); - sint min = std::numeric_limits::min(); sint result; // // test operator+ @@ -128,8 +139,10 @@ int main() { // result = min * sint(2); // std::cout << result << '\n'; - // // test operator/ + // test operator/ // result = sint(42) / sint(0); - // cout << result << '\n'; + // std::cout << result << '\n'; + // result = min / sint(-2); + // std::cout << result << '\n'; return 0; } \ No newline at end of file diff --git a/src/sheet03.cpp b/src/sheet03.cpp old mode 100644 new mode 100755 diff --git a/src/sheet04.cpp b/src/sheet04.cpp old mode 100644 new mode 100755 diff --git a/src/sheet05.cpp b/src/sheet05.cpp old mode 100644 new mode 100755 index e69de29..a4e5f5a --- a/src/sheet05.cpp +++ b/src/sheet05.cpp @@ -0,0 +1,176 @@ +//===----------------------------------------------------------------------===// +// +// Philipp Schubert +// +// Copyright (c) 2017 - 2021 +// Secure Software Engineering Group +// Heinz Nixdorf Institute +// Paderborn University +// philipp.schubert@upb.de +// +//===----------------------------------------------------------------------===// + +// #include +// #include +#include +#include +#include +#include + +constexpr int max = std::numeric_limits::max(); +constexpr int min = std::numeric_limits::min(); + +class sint { + private: + int value; + + public: + sint() : value(0) {} + sint(int i) : value(i) {} + ~sint() = default; + sint(const sint &s) = default; + sint &operator=(const sint &s) = default; + sint(sint &&s) = default; + sint &operator=(sint &&s) = default; + int getUnderlyingValue() const noexcept { return value; } + friend sint operator+(sint lhs, sint rhs) + { + int result; + if(__builtin_sadd_overflow(lhs.getUnderlyingValue(), rhs.getUnderlyingValue(), &result)) + { + throw std::overflow_error("addition overflow"); + } + return result; + } + friend sint operator-(sint lhs, sint rhs) + { + int result; + if(__builtin_ssub_overflow(lhs.getUnderlyingValue(), rhs.getUnderlyingValue(), &result)) + { + throw std::overflow_error("subtraction overflow"); + } + return result; + } + + friend sint operator*(sint lhs, sint rhs) + { + int result; + if(__builtin_smul_overflow(lhs.getUnderlyingValue(), rhs.getUnderlyingValue(), &result)) + { + throw std::overflow_error("multiplication overflow"); + } + return result; + } + + friend sint operator/(sint lhs, sint rhs) + { + if(rhs.getUnderlyingValue()==0) + { + throw std::overflow_error("division by 0"); + } + + //If two's complement + constexpr bool twos = min != -max; + if(twos && lhs.getUnderlyingValue() == min && rhs.getUnderlyingValue() == -1) + { + throw std::overflow_error("division with integer maximum and -1"); + } + + return lhs.getUnderlyingValue()/rhs.getUnderlyingValue(); + } + + sint &operator++() + { + *this = *this + 1; + return *this; + } + sint operator++(int) + { + sint out(*this); + ++(*this); + return out; + } + + sint &operator--() + { + *this = *this - 1; + return *this; + } + sint operator--(int) + { + sint out(*this); + --(*this); + return out; + } + friend std::ostream &operator<<(std::ostream &os, const sint &s) + { + return os << s.getUnderlyingValue(); + } +}; + +const sint smax = max; +const sint smin = min; + +struct Node { + int data; + Node *next; + Node(int i) : data(i), next(nullptr) {} + friend std::ostream &operator<<(std::ostream &os, const Node &n) + { + os << "Node\n" + << "\tdata: "<< n.data << "\n\tthis: " << &n + << "\n\tnext: " << n.next; + return os; + } +}; + +void addElement(Node **head, int data) +{ + if(*head == nullptr) + { + *head = new Node(data); + return; + } + + Node **next = &(**head).next; + do + { + *next = (**next).next; + } + while(*next != nullptr) + *next = new Node(data); +} +void printList(const Node *head) +{ + std::cout << *head << '\n'; + Node *next = (*head).next; + std::cout << (next != nullptr) << '\n'; + while(next != nullptr) + { + std::cout << *next << '\n'; + next = (*next).next; + } +} +void deleteList(Node *head) +{ + Node *next; + do + { + next = (*head).next; + delete head; + head = next; + }while(head != nullptr); +} + + +int main() +{ + Node *list = nullptr; + addElement(&list, 1); + addElement(&list, 2); + addElement(&list, 3); + addElement(&list, 4); + printList(list); + deleteList(list); + return 0; +} \ No newline at end of file