1

In this code:

// Stack using LinkedList //

#include <stdio.h>
#include <stdlib.h>

struct Node {
    int data;
    struct Node* next;
};

struct Node* top = NULL;

short isEmpty(void) {
    if (top == NULL) {
        printf("error: The stack is empty.\n");
        return 1;
    }
    
    return 0;
}

void push(int value) {
    struct Node* newNode = (void*)malloc(sizeof(struct Node));
    if (!newNode) {
        printf("error: Heap overflow!\n");
        exit(1);
    }
    
    newNode->data = value;
    newNode->next = top;
    top = newNode;
}

int pop(void) {
    if (isEmpty()) {
        exit(1);
    }
    
    struct Node* ref = top;
    int val = top->data;
    top = top->next;
    free(ref);
    
    return val;
}

int peek(void) {
    if (isEmpty()) {
        exit(1);
    }
    
    return top->data;
}

void display(void) {
    if (isEmpty()) {
        exit(1);
    }
    
    while (top) {
        printf("%d\n", top->data);
        top = top->next;
    }
}

int main(void) {
    push(10);
    push(20);
    push(30);
    push(40);
    
    printf("Peek: %d\n", peek());
    int val = pop();
    printf("Popped: %d, now Peek: %d\n", val, peek());
    push(50);
    display();
    
    return 0;
}

Have a look at these lines:

int val = pop();
printf("Popped: %d, now Peek: %d\n", val, peek());

It returns: Popped: 40, now Peek: 30

as expected. However, when writing it this way:

printf("Popped: %d, now Peek: %d\n", pop(), peek());

It yields this output: Popped: 40, now Peek: 40

Here's a Godbolt.

Can somebody enlighten me as to why it is that way?

3
  • 2
    The order of evaluation of function arguments is not guaranteed. See: Parameter evaluation order before a function calling in C. Commented Apr 29 at 4:08
  • @wohlstad oh, dang! I see. I've been programming in C for years, read books, and still feel like an infant. smh Commented Apr 29 at 4:17
  • Order of evaluation would be on the list of important things that many programming classes for some reason fail to mention. Many subpar teachers don't even know about order of evaluation and think it is the same as operator precedence. Commented Apr 29 at 13:24

1 Answer 1

4

The order of evaluation of function arguments is unspecified. So when you do this:

printf("Popped: %d, now Peek: %d\n", pop(), peek());

Either pop or peek could be called first.

In your particular case, peek was apparently called first which returned the value 40 without removing the value from the stack, then the pop call removes that value from the stack and returns it, so 40 is printed both times.

Sign up to request clarification or add additional context in comments.

4 Comments

Oh, I see. That's quite counterintuitive, though. +1 I don't understand why my particular case remains unchanged even in Godbolt and through multiple executions in my system.
@RohanBari Once the program is compiled it's unlikely that order will change, however making code changes or changing compiler settings could potentially alter which gets called first.
Ah! Now, I understand why UB is undefined, even though the same output is generated consistently. It depends on compiler settings and other aspects of the program. Right?
@RohanBari I wouldn't use "UB" for that. There's a difference between UB and unspecified or implementation defined behavior. See: Undefined, unspecified and implementation-defined behavior.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.