So, I'm trying to make this binary tree program in C and it just keeps throwing the darndest compile errors. Whenever I change something to find what is causing the error, it changes! I have not forgotten my include guards, I used #pragma once. If I place the struct in the header I get incompatible types, if I put it in the .c I get a redefinition of pretty_print which goes away when I rename pretty_print. As I trim out the other functions in bintree.c and the header, the error changes to intTree being undefined. If I then change intTree to just int it becomes incompatible types. This goes away if I merge the header into the .c. Now it's gone. I think these might be seperate errors and the changing error might be my bad, but it is happening an I have no idea why. I will present code that demonstrates as many of these, but whenever I try to duplicate what I did it throws a different error. But I'm not frustrated. I would like to be able to post a well-formatted question with helpful information, but I have none, despite spending several hours on this program.
bintree.cxx
#include "bintree.h"
int add(intTree* root,int key,void* val){
    if(!root){
        root=malloc(sizeof(intTree));
        if(!root){
            return 1;
        }
        root->key=key;
        root->val=val;
        root->left=0;
        root->right=0;
        return 0;
    }
    if(key>root->key){
        if(root->right){
            return add(root->right,key,val);
        }else{
            root->right=(intTree*) malloc(sizeof(intTree));
            if(!root->right){
                return 1;
            }
            root->right->key=key;
            root->right->val=val;
            root->right->left=0;
            root->right->right=0;
            return 0;
        }
    }
    if(key<root->key){
        if(root->left){
            return add(root->left,key,val);
        }else{
            root->left=malloc(sizeof(intTree));
            if(!root->left){
                return 1;
            }
            root->left->key=key;
            root->left->val=val;
            root->left->left=0;
            root->left->right=0;
            return 0;
        }
    }
    return 2;
}
void* get(intTree* root,int key){
    if(!root){
        return 0;
    }
    if(key>root->key){
        return get(root->right,key);
    }
    if(key<root->key){
        return get(root->left,key);
    }
    return root->val;
}
int remove_root(intTree* root){
    if(!root){
        return 1;
    }
    if(root->right){
        root->key=root->right->key;
        root->val=root->right->val;
        return remove_root(root->right);
    }
    if(root->left){
        root->key=root->left->key;
        root->val=root->left->val;
        return remove_root(root->left);
    }
    free(root);
    return 0;
}
int remove_node(intTree* root,int key){
    if(!root){
        return 1;
    }
    if(key>root->key){
        return remove_node(root->right,key);
    }
    if(key<root->key){
        return remove_node(root->left,key);
    }
    return remove_root(root);
}
void delete(intTree* root){
    if(root){
        delete(root->right);
        delete(root->left);
        free(root);
    }
}
void pretty_print(intTree* root,int ws,int wso,void (*print_val)(void*)){
    if(!root) return;
    printf("%*s",ws,"");
    print_val(root->val);
    pretty_print(root->left,ws+wso,wso,print_val);
    pretty_print(root->right,ws+wso,wso,print_val);
}
bintree.h
#pragma once
#include <stdlib.h>
typedef struct intTree_s{
    int key;
    void* val;
    struct intTree_s* left;
    struct intTree_s* right;
} intTree;
int add(intTree*,int,void*);
void* get(intTree*,int);
int remove_root(intTree*);
int remove_node(intTree*,int);
void delete(intTree*);
void pretty_print(intTree*,int,int,void(*)(void*));
These throw hundreds of errors about intTree being an incomplete type. This persists for whichever format of typedef/struct I use to define intTree.
bintree.c
#include "pretty_print.h"
void pretty_print(void){return;}
pretty_print.h
void pretty_print(void);
Throws conflicting types for "pretty_print", though it does not if I rename to "p", inline the header, or change the arguments to "int v". This also works with the arguments "int* a,void()(void)", as in the original program.
Final "error": warns about implicit redefinition of malloc, free, printf, and puts.
bintree.cxx
struct intTree_s{
    int key;
    void* val;
    struct intTree_s* left;
    struct intTree_s* right;
};
typedef struct intTree_s intTree;
int add(intTree* root,int key,void* val){
    if(!root){
        root=malloc(sizeof(intTree));
        if(!root){
            return 1;
        }
        root->key=key;
        root->val=val;
        root->left=0;
        root->right=0;
        return 0;
    }
    if(key>root->key){
        if(root->right){
            return add(root->right,key,val);
        }else{
            root->right=(intTree*) malloc(sizeof(intTree));
            if(!root->right){
                return 1;
            }
            root->right->key=key;
            root->right->val=val;
            root->right->left=0;
            root->right->right=0;
            return 0;
        }
    }
    if(key<root->key){
        if(root->left){
            return add(root->left,key,val);
        }else{
            root->left=malloc(sizeof(intTree));
            if(!root->left){
                return 1;
            }
            root->left->key=key;
            root->left->val=val;
            root->left->left=0;
            root->left->right=0;
            return 0;
        }
    }
    return 2;
}
void* get(intTree* root,int key){
    if(!root){
        return 0;
    }
    if(key>root->key){
        return get(root->right,key);
    }
    if(key<root->key){
        return get(root->left,key);
    }
    return root->val;
}
int remove_root(intTree* root){
    if(!root){
        return 1;
    }
    if(root->right){
        root->key=root->right->key;
        root->val=root->right->val;
        return remove_root(root->right);
    }
    if(root->left){
        root->key=root->left->key;
        root->val=root->left->val;
        return remove_root(root->left);
    }
    free(root);
    return 0;
}
int remove_node(intTree* root,int key){
    if(!root){
        return 1;
    }
    if(key>root->key){
        return remove_node(root->right,key);
    }
    if(key<root->key){
        return remove_node(root->left,key);
    }
    return remove_root(root);
}
void delete(intTree* root){
    if(root){
        delete(root->right);
        delete(root->left);
        free(root);
    }
}
void pretty_print(intTree* root,int ws,int wso,void (*print_val)(void*)){
    if(!root) return;
    printf("%*s",ws,"");
    print_val(root->val);
    pretty_print(root->left,ws+wso,wso,print_val);
    pretty_print(root->right,ws+wso,wso,print_val);
}
I can't seem to generate the original error, which was about a redefinition of pretty_print, again. I apoligize for how little I know about this problem (basically just that it is).
 
     
    