9
typedef int A;
typedef int B;

void foo(A arg){}

void main(void){
    B wrongvar = 7;
    foo(wrongvar);
}

Is this construction supposed to return a warning/error, according to the standard? What about the most popular compilers?

Example: we have variables, representing kilograms and meters, and all are type 'int'. We have a function, processing meters. We want the compiler to catch bugs, related to passing kilograms meaning variables variables to that function.

I believe Ada handles that smoothly. What about modern C?

Vorac
  • 8,726
  • 11
  • 58
  • 101
  • 1
    A `typedef` gives a new name to an existing type; it doesn't create a new type. The alternative names also refer to the same type. Thus, all of `A`, `B`, `int` and `signed int` can be passed to `foo(A arg)` without a type violation (and other types convertible to `int`, such as `enum` types, can also be passed without eliciting a warning). – Jonathan Leffler Apr 28 '13 at 17:21
  • `void main(void)` should be `int main(void)` -- and whatever reference told you to use `void main(void)` was written by someone who doesn't know C very well. – Keith Thompson Mar 02 '16 at 21:06
  • @KeithThompson, c99 seems to [support](http://stackoverflow.com/a/9356660/1145760) this use of `void main(void)`. The misunderstanding is because I have not correctly tagged the question. – Vorac Mar 07 '16 at 08:16
  • In all editions of the C standard, an implementation is allowed, but not required, to permit additional forms, including `void main(void)`. There was no relevant change in C99. But `int main(void)` is supported by *all* conforming hosted C implementations. Unless you're programming for an embedded system, there is no good reason to use `void main(void)`. – Keith Thompson Mar 07 '16 at 08:20

2 Answers2

9

No, what you're dealing with is a type discipline issue known as structural equivalence vs name equivalence. As Dog said, the closest thing you could do to achieve what you want is use structs, but this could be a waste of memory if the compiler chooses to add padding (which in this case is unlikely). C uses structural equivalence (meaning the two types are the same thing) for aliases, but name equivalence for different declared structs (two struct types with the same layout are not treated as equivalent).

An example of using structs to do this:

typedef struct {
    double value;
} meters;

typedef struct {
    double value;
} kilograms;

int main(){
    meters m;
    kilograms k = {2}; // initialized
    m.value = 1;
    k = m; // error, can't assign meters to kilos
    return 0;
}

You may wish to read this article: http://www.joelonsoftware.com/articles/Wrong.html describing how you can help avoid these issues with naming conventions

Ryan Haining
  • 35,360
  • 15
  • 114
  • 174
2

You could use a struct with one field to do exactly what you want. The only "downside" is that you'll potentially waste 1/2/4/8 bytes if the optimizer doesn't optimize them out...

Dog
  • 7,707
  • 8
  • 40
  • 74
  • 4
    Size of struct is just the sum of sizes of its member variables plus any padding (if required). In case of only one member variable I don't think there would be any overhead in terms of space. – A. K. Apr 28 '13 at 16:34