11 May, 2009, JohnnyStarr wrote in the 1st comment:
Votes: 0
hey,
i noticed this in ROM: CHAR_DATA *victim = (CHAR_DATA *) vo;
Ok, so i'm not a C expert (YET) so could someone explain this? is this how type casting in C works?
If so, why is this done THIS way?
11 May, 2009, David Haley wrote in the 2nd comment:
Votes: 0
Yes, that is type casting.

Quote
If so, why is this done THIS way?

I'm guessing this isn't a syntax question.
Basically, 'vo' is something that is not of type CHAR_DATA* (probably void*), but somehow it has been determined that it actually is a CHAR_DATA*, so you need to tell the compiler what its real type is in order to use it as a pointer to a CHAR_DATA structure.
11 May, 2009, JohnnyStarr wrote in the 3rd comment:
Votes: 0
I see, so you are correct (yet again) 'vo' was a parameter sent in as void.

so i guess my next question is, why would it be sent in as void? it was a spell function in magic.c

i suppose i mean to ask, what is the advantage of sending something in as void? is it that vo could have been a pointer to CHAR_DATA OR an integer? or even a pointer to a char 'string'?
11 May, 2009, David Haley wrote in the 4th comment:
Votes: 0
Yes, since C/C++ are statically typed languages, everything needs a type. So, if you don't know something's type ahead of time, you need to use some kind of generic type. void* is the easiest way to pass something in without actually specifying a type.

In this case, 'vo' might be a pointer to a character, a string, an object, maybe a room or an area or who knows what. Given where it's used (as an argument to a spell) it is likely that in practice it is either a character or an object – i.e. some kind of target.

This kind of programming is "dangerous" in that you are basically overriding the compiler's type checking system, but sometimes you don't have much of a choice. (Of course, there are better and worse ways of implementing dynamic typing.)
11 May, 2009, elanthis wrote in the 5th comment:
Votes: 0
It's because C lacks a standard way of defining polymorphic types or type sets. The easy way of working around that is to use void pointers. Some toolkits will make a "variant" struct that looks something like:

typedef enum { TYPE_CHAR, TYPE_STRING, TYPE_INT, TYPE_OBJECT } type_t;
typedef struct {
type_t type;
union {
CHAR_DATA *cd;
char *str;
int i;
} d;
} variant_t;

void my_func(variant_t data) {
if (data.type == TYPE_STRING)
do_something(data.d.str);
}


Using C++, you can do the same thing but make the resulting code much cleaner looking and easier to use without all the extra checks and stuff the C version would require. Which is one of the many, many reasons most developers prefer C++ over C for general application development (and one of the few reasons to prefer C++ over C# or Java or the like, which have a very strict type hierarchy and no means of creating advanced user-defined types that can behave like PODs).
11 May, 2009, JohnnyStarr wrote in the 6th comment:
Votes: 0
I see.
This sheds a ton of light to my understanding of dynamic typing.
So, could it be argued that it would be a 'safer' practice to asses
what a parameter is before its sent?

Does C have a multi argument ability?

Ruby:

my_function(*args)

call-> my_function(player, argument, object)
11 May, 2009, elanthis wrote in the 7th comment:
Votes: 0
Quote
This sheds a ton of light to my understanding of dynamic typing.
So, could it be argued that it would be a 'safer' practice to asses
what a parameter is before its sent?


Yes and no. It can never be truly safe in C because you as the programmer end up being the one to make the decision, and you have to write code that abides by those decisions in both the caller and callee. Even if you pass in a variant to a C function, nothing stops you from misusing that variant. All it really does it make it possible to pass in the extra data so that you can write safer code, at the cost of having to write more of it.

You can never make it rock solid in. If you want to make code type safe without totally rewriting, you need to start using C++, which has the ability to select different code paths (at both runtime and compilation time) based on the types being used. Its runtime type polymorphism is very weak compared to a 'dynamic' language, but its compile-time polymorphism (via generics/templates and overloading) can be used to easily implement a variety of pleasant APIs that dynamic languages make doing a pain in the ass. For example, a C++ variant type combined with functors makes it possible to develop an API for spells that accurately captures the types passed in and refuses to execute a spell if the types don't match what the spell is expecting. You'd have to write a fair bit of C++ code to do that, but once written you can add as many spells as you want without fear of crashed caused by type mismatches again.

In a way, for this particular case, it'd be no different than using a dynamic language other than requiring more typing. A dynamic language doesn't magically make passing arbitrary types work. All it does is let you both pass arbitrary types (just like C does via void* pointers) while allowing you to find the type of an arbitrary value (unlike C but sorta like C++) and manually check the type (like C++ can). What a statically typed language brings you is performing that check at compile time and shaving down the size of your code (in some places). The dynamic language might need:

function (foo, bar):
if foo is not a string:
raise "foo ain't a string"
if bar is not a player:
raise "bar ain't a player"
do_stuff


While C/C++ can do:

function (string foo, player bar) {
do_stuff();
}


Way shorter there. But as soon as you need variable arguments or variant types, the C/C++ code blows up in size compared to the dynamic code. C++ has facilities to make those safer compared to C, but it doesn't make it as easy as a dynamic language. I personally prefer statically typed languages (assuming they're not too strict and limited) because I need variant types very, very rarely, so to me it makes more sense to "optimize" the language syntax for the non-variant case than for the variant one. Plus C++ does make simple variant types relatively easy to do, especially if you just use one of the prewritten libraries like Boost::Any.

Quote
Does C have a multi argument ability?


C has varargs. Which takes a bit of understanding to use. You can in a way think of it the same as passing in a series of void* (you're not really), which means you have no idea what the types are on its own. That's why printf() and the like use the format specifies – it needs to know what each additional argument you passed actually is.

There is no way to build up a list of arguments to pass to a function without using a third-party non-portable library, e.g. libffi.


Remember, C is just a very thin veneer over raw machine programming. It turns infix math into postfix math and it translates if statements and loops into simple labels and jumps (again, very very simplified explanation there) and that's about all it does over raw assembler. It is not a higher order programming language, nor does it even remotely try to pretend otherwise. C++ does try to pretend (especially the upcoming C++0x version) but it only goes so far. In particular, both C and C++ are intended to be usable without any standard library (hence making them usable for kernel programming and other low level system tasks) where as high order languages (be they static or dynamic) all require at least a small core runtime to be usable at all. As consequence, C/C++ cannot include any language features that can't easily be translated directly into assembler/machine code, while other languages can include features that may require a large amount of framework code to actually implement. C/C++ include code in their respective standard libraries that helps out for a variety of higher order programming tasks, and C++ makes it a good deal easier to develop higher order library components, but at their core they are devoid of any higher order capabilities.
11 May, 2009, JohnnyStarr wrote in the 8th comment:
Votes: 0
dang elanthis, thanks for all the info.

since you brought up C++0X, and i was wondering about the standard IDE for C++, is C++ under GNU, or is it 'owned', i know borland has a compiler of course, but with the new C++ is there going to be a new comipler or IDE?
12 May, 2009, quixadhal wrote in the 9th comment:
Votes: 0
One of the big annoyances with C is trying to use varargs to do anything ELSE but printf-style formatting. :)

In particular, if you're walking through the arguments using va_arg(), you need to know not only what type each argument is, but how many there are.

Quote
The first use of the va_arg() macro after that of the va_start() macro returns the argument after last. Succes-
sive invocations return the values of the remaining arguments.

If there is no next argument, or if type is not compatible with the type of the actual next argument (as promoted
according to the default argument promotions), random errors will occur.


Ugly stuff. So, in practice… you have to pass some information in one or more fixed arguments that your routine can then use to figure out what to expect next. Pain in the rear.
12 May, 2009, David Haley wrote in the 10th comment:
Votes: 0
If you really need variable arguments, it's usually easier to pass in a vector/list or in general any iterator over the type of thing you need several of. There are relatively few instances where you really need free-form varargs; printf is a canonical example. In C++, you would achieve it using streams.

I don't know how much sense it makes to speak of a "standard IDE for C++". There are several ones that many people use (Visual Studio is a big one on Windows) but the C++ standard committee has little interest in implementing compilers, much less full IDEs. The big compilers are VS (Microsoft's), gcc (GNU), Sun's, and Intel's. There are some up-and-coming compilers too, like the LLVM compiler family. I don't know many people who actually use Borland's compiler these days, but that's just my experience.
12 May, 2009, elanthis wrote in the 11th comment:
Votes: 0
staryavsky said:
since you brought up C++0X, and i was wondering about the standard IDE for C++, is C++ under GNU, or is it 'owned'


Neither. It is an international standard, the official specification for which is under the direction of ISO. C++ committee.

Quote
i know borland has a compiler of course, but with the new C++ is there going to be a new comipler or IDE?


The various compilers and IDEs will be updated to support the new features. Many compilers already have some partial support for it, including the latest version of GCC. That support is experimental and not recommended to be used yet, mind you. We sadly are unlikely to see full C++0x support in any major compiler for another 2-3 years. The C++0x feature additions are pretty huge and complex.
0.0/11