Stack implementation in C
Your clear function uses while (--sp &gt; 0); when sp = 0; does the same thing in faster and clearer way. also consider not throwing an error when clearing an empty stack, because it still behaves as expected.
The condition sp &gt; 0 &amp;&amp; (sp - 1) &gt; 0 is esentially just sp &gt; 1 or sp &gt;= 2, which I would prefer, but that is just a matter of personal style.
Instead of using val[sp-1] to get the top element of the array (in swap and duplicate) use the top() function, as it is a good idea to express your stack operations in terms of more primitive stack operations.
Follwing the concept of the defining operation in terms of primitive operations, duplicate can be written as:

void duplicate(void) {
    push(top());
}


and swap can be written as:

void swap(void) {
    int elem1 = pop();
    int elem2 = pop();
    push(elem1);
    push(elem2);
}


Notice how there is no error checking in these functions,
because push(), pop(), and top() handle the full or empty
stack for us.