473,385 Members | 1,409 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

Generics in C

This post is about how to get generic modules in a C environment. The
aim is to get close to Ada generics. Using C++ is not an option. It
should all run in a simple C compiler.

When I think of a generic module, it is something that can be used
exactly as it is. The generic H-file and/or C-file, should not have to
be edited AT ALL in order to use it. If it has to be changed in just 1
line, it could possibly still have great reusability properties, but it
is not generic in the sense I mean.

I am going to give a suggestion for a way to do generics, by presenting
5 files as an example. I would very much like comments on how things
could be simplified or extended, but still using only C.

Ok, here we go. Lets say, we want to implement generic powers, by
repeating multiplication. The user of the module have to provide the
type, and a function that performs multiplication on that type.

The generic module is represented by GenPower.h and GenPower.c. The
instantiation module is My.h and My.c, and then we have a test program.
The test program will calculate 3^5 = 3*3*3*3*3 = 243. It is compiled
and run in VC6.

Running the test program prints this to stdout:
Result of power = 243

Let me know what you think of the idea. Good? Bad? Old?
Complicated? (In that case I agree, but I think it is worth it.)
// File GENPOWER.H
// Formal Generic Parameters:
// INSTANCE The name of the instance module.
// ATYPE The instance type.
// (INSTANCE)_Multiply Multiplication function for the type.
// (See prototype below for details.)
//
// void INSTANCE_Multiply(ATYPE *, ATYPE);
// is implemented in your module, otherwise it will be
// missed at link time.
//
// Details of formal parameter functions:
#define MODULE_Multiply INSTANCE()##_Multiply
void MODULE_Multiply(ATYPE *first_operand_and_result, ATYPE
other_operand);
//
// Package: (What this module provides generically)
#define MODULE_Power INSTANCE()##_Power
void MODULE_Power (ATYPE *result, int exponent);
//
// End of file
// File GENPOWER.C
// This is just for #include -ing, Do not link this module.
#include "GenPower.h"
void MODULE_Power (ATYPE *result, int exponent)
{ // Exponent must be at least 1.
ATYPE a;
int i;
a = *result;
for (i=1; i<exponent; i++) {
MODULE_Multiply (result, a);
}
}
// File MY.H
typedef unsigned long MYTYPE;
// Ok, now we have declared our type, lets get the power function
// by instantiating the generic power module:
#define INSTANCE() MY
#define ATYPE MYTYPE
#include "GenPower.H"
//
void MY_Multiply(MYTYPE *, MYTYPE);
// End of file
// File MY.C
#include "my.h"
#include "genpower.c"
// Yes we are including the C file, not the H file.
// That way we actually get an implementation of the function
// void MYTYPE_Power(MYTYPE *, int) right here in this module.
// Of course, we also have to provide the multiplication function:
void MY_Multiply(MYTYPE *first_operand_and_result, MYTYPE
other_operand)
{
// Do something multiplicatish.
(*first_operand_and_result) *= other_operand;
}
// End of file
// Test program
#include <stdio.h>
#include "my.h"
int main(int argc, char* argv[])
{
MYTYPE a;
a = 3;
MY_Power(&a, 5);
printf ("Result of power = %d\n", (int) a);
return 0;
}
// End of file

Jan 13 '07 #1
18 2367
ttl_id...@yahoo.com wrote:
This post is about how to get generic modules in a C environment. The
aim is to get close to Ada generics. Using C++ is not an option. It
should all run in a simple C compiler.

When I think of a generic module, it is something that can be used
exactly as it is. The generic H-file and/or C-file, should not have to
be edited AT ALL in order to use it. If it has to be changed in just 1
line, it could possibly still have great reusability properties, but it
is not generic in the sense I mean.

I am going to give a suggestion for a way to do generics, by presenting
5 files as an example. I would very much like comments on how things
could be simplified or extended, but still using only C.

Ok, here we go. Lets say, we want to implement generic powers, by
repeating multiplication. The user of the module have to provide the
type, and a function that performs multiplication on that type.
In my opinion, that defeats the purpose of generic programming.

<snip>

Jan 13 '07 #2
santosh wrote:
ttl_id...@yahoo.com wrote:
This post is about how to get generic modules in a C environment. The
aim is to get close to Ada generics. Using C++ is not an option. It
should all run in a simple C compiler.

When I think of a generic module, it is something that can be used
exactly as it is. The generic H-file and/or C-file, should not have to
be edited AT ALL in order to use it. If it has to be changed in just 1
line, it could possibly still have great reusability properties, but it
is not generic in the sense I mean.

I am going to give a suggestion for a way to do generics, by presenting
5 files as an example. I would very much like comments on how things
could be simplified or extended, but still using only C.

Ok, here we go. Lets say, we want to implement generic powers, by
repeating multiplication. The user of the module have to provide the
type, and a function that performs multiplication on that type.

In my opinion, that defeats the purpose of generic programming.
The purpose of generics is to write algorithms once, and allow them to
apply to different types. The OP's proposal is not as general as it
could be, but it is *one* form of generic programming. I give another
more general approach in the following examples:

http://www.pobox.com/~qed/ll.zip
http://www.pobox.com/~qed/gstack.zip

--
Paul Hsieh
http://www.pobox.com/~qed/
http://bstring.sf.net/

Jan 13 '07 #3
"santosh" <sa*********@gmail.comwrites:
ttl_id...@yahoo.com wrote:
[...]
>Ok, here we go. Lets say, we want to implement generic powers, by
repeating multiplication. The user of the module have to provide the
type, and a function that performs multiplication on that type.

In my opinion, that defeats the purpose of generic programming.

<snip>
I disagree. It would be nice if the generic module could infer the
appropriate multiplication operator given the type (<OT>as Ada
generics can do</OT>), but that's difficult or impossible to do in C.

Note also that it doesn't just *require* you to provide a
multiplication function, it *allows* you to do so. If you provide a
function that performs addition, the generic will perform
multiplication. It provides a generic way to specify applying some
arbitrary operation repeatedly. In a sense, that's more generic than
just providing a power function.

(I haven't read the code closely enough to verify that this will
actually work.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Jan 13 '07 #4

"Keith Thompson" <ks***@mib.orgwrote in message
>
I disagree. It would be nice if the generic module could infer the
appropriate multiplication operator given the type (<OT>as Ada
generics can do</OT>), but that's difficult or impossible to do in C.

Note also that it doesn't just *require* you to provide a
multiplication function, it *allows* you to do so. If you provide a
function that performs addition, the generic will perform
multiplication. It provides a generic way to specify applying some
arbitrary operation repeatedly. In a sense, that's more generic than
just providing a power function.

(I haven't read the code closely enough to verify that this will
actually work.)
Part of the solution is to have a few types as possible muddying typespace.

However there are some basic functions that most generic operators need.
Namely clone, copy, destroy, serialise, deserialise, print as human-readable
string.

Maths operators are a bit of a red herring. It is nice in theory to
implement an average that works on huge integers and complex types. In
practise, it is easy enough to roll your own, because the need doesn't arise
sufficiently often. In any case, there are problems inherent in the
process - the average of a list of integers is a real, for instance, so what
is the average of a list of huge integers supposed to be?.
Jan 13 '07 #5
tt*******@yahoo.com wrote:
// File MY.H
typedef unsigned long MYTYPE;
// Ok, now we have declared our type, lets get the power function
// by instantiating the generic power module:
#define INSTANCE() MY
#define ATYPE MYTYPE
#include "GenPower.H"
//
void MY_Multiply(MYTYPE *, MYTYPE);
// End of file
// File MY.C
#include "my.h"
#include "genpower.c"
// Yes we are including the C file, not the H file.
// That way we actually get an implementation of the function
// void MYTYPE_Power(MYTYPE *, int) right here in this module.
// Of course, we also have to provide the multiplication function:
void MY_Multiply(MYTYPE *first_operand_and_result, MYTYPE
other_operand)
{
// Do something multiplicatish.
(*first_operand_and_result) *= other_operand;
}
// End of file
// Test program
#include <stdio.h>
#include "my.h"
What happens if you want to work with more than one type? my.h has
already defined INSTANCE() and MTYPE.
int main(int argc, char* argv[])
{
MYTYPE a;
a = 3;
MY_Power(&a, 5);
printf ("Result of power = %d\n", (int) a);
return 0;
}
// End of file

--
Ian Collins.
Jan 13 '07 #6
In article <11**********************@51g2000cwl.googlegroups. com>,
<tt*******@yahoo.comwrote:
>This post is about how to get generic modules in a C environment. The
aim is to get close to Ada generics. Using C++ is not an option. It
should all run in a simple C compiler.
[...]
>Let me know what you think of the idea. Good? Bad? Old?
Complicated? (In that case I agree, but I think it is worth it.)
Unnecessarily complicated.

Comment #1: If you want {C++|Ada|whatever}, you know where to find it.
Comment #2: What's wrong with a qsort-style interface?
dave

--
Dave Vandervies dj******@csclub.uwaterloo.ca

English was never my strong point.
--Richard Heathfield in comp.lang.c
Jan 14 '07 #7
What happens if you want to work with more than one type? my.h has
already defined INSTANCE() and MTYPE.
Good question. I get 2 warnings. One for redefining INSTANCE() and one
for redefining ATYPE. But it compiles and gives the correct result. And
I can't #undef them in the end of GenPower.h. Hmm.

Jan 14 '07 #8
Dave Vandervies wrote:
<tt*******@yahoo.comwrote:
>This post is about how to get generic modules in a C environment.
The aim is to get close to Ada generics. Using C++ is not an
option. It should all run in a simple C compiler.

[...]
>Let me know what you think of the idea. Good? Bad? Old?
Complicated? (In that case I agree, but I think it is worth it.)

Unnecessarily complicated.

Comment #1: If you want {C++|Ada|whatever}, you know where to find it.
Comment #2: What's wrong with a qsort-style interface?
Take a look at how hashlib handles generic structures for storing,
access, etc. It needs nothing unusual or questionable.
Dog-standard C.

<http://cbfalconer.home.att.net/download/>

--
"I conclude that there are two ways of constructing a software
design: One way is to make it so simple that there are obviously
no deficiencies and the other way is to make it so complicated
that there are no obvious deficiencies." -- C. A. R. Hoare
Jan 14 '07 #9
In article <lo*********************@bt.com>,
Malcolm McLean <re*******@btinternet.comwrote:
>Maths operators are a bit of a red herring. It is nice in theory to
implement an average that works on huge integers and complex types. In
practise, it is easy enough to roll your own, because the need doesn't arise
sufficiently often.
Taking an average is something that is easy to get wrong: as soon as
you are working with floating point types (including those buried
in a complex), you need to sort the values before doing the additions,
because otherwise you risk losing precision and risk other numeric
sins.

There are a bunch of common algorithms that people -think-
"are easy enough to roll your own", but really aren't. And so few people
invest in Knuth these days :(
--
"No one has the right to destroy another person's belief by
demanding empirical evidence." -- Ann Landers
Jan 14 '07 #10

"Walter Roberson" <ro******@ibd.nrc-cnrc.gc.cawrote in message
In article <lo*********************@bt.com>,
Malcolm McLean <re*******@btinternet.comwrote:
>>Maths operators are a bit of a red herring. It is nice in theory to
implement an average that works on huge integers and complex types. In
practise, it is easy enough to roll your own, because the need doesn't
arise
sufficiently often.

Taking an average is something that is easy to get wrong: as soon as
you are working with floating point types (including those buried
in a complex), you need to sort the values before doing the additions,
because otherwise you risk losing precision and risk other numeric
sins.

There are a bunch of common algorithms that people -think-
"are easy enough to roll your own", but really aren't. And so few people
invest in Knuth these days :(
If you are writing a general-purpose, resuable, high quality average routine
then, yes, sorting by magnitude is one thing you can do to ensure maximum
precision.
For the vast majority of applications there is no need to do this, so "roll
your own" can be better.
Jan 14 '07 #11
"CBFalconer" <cb********@yahoo.comwrote in message
Dave Vandervies wrote:
><tt*******@yahoo.comwrote:
>>This post is about how to get generic modules in a C environment.
The aim is to get close to Ada generics. Using C++ is not an
option. It should all run in a simple C compiler.

[...]
>>Let me know what you think of the idea. Good? Bad? Old?
Complicated? (In that case I agree, but I think it is worth it.)

Unnecessarily complicated.

Comment #1: If you want {C++|Ada|whatever}, you know where to find it.
Comment #2: What's wrong with a qsort-style interface?

Take a look at how hashlib handles generic structures for storing,
access, etc. It needs nothing unusual or questionable.
Dog-standard C.

<http://cbfalconer.home.att.net/download/>
Take a look at my simulated annealing code
http://www.personal.leeds.ac.uk/~bgy1mm

it is also generic, but I am not happy with it. The problem is that the
caller has to know how to implement all the functions, and what to do with
the global pointer. All very fiddly. Obviously I want anneal(void *obj,
double (*score)(void *), void (*mutate)(void *)), not lots of housekeeping
parameters.
Jan 14 '07 #12
<tt*******@yahoo.comwrote:
This post is about how to get generic modules in a C environment. The
aim is to get close to Ada generics. Using C++ is not an option. It
should all run in a simple C compiler.

[...]
Dave Vandervies wrote:
[...]
Comment #2: What's wrong with a qsort-style interface?
It is not close to Ada, and the style only works for functions, not for
modules. (?)

I don't like function pointers. Anyway, the hardware we use makes it
impossible to use function pointers. It has to do with fixed adresses
for variables that would normally be on the stack, and a very small
RAM.
English was never my strong point.
--Richard Heathfield in comp.lang.c
Mine either.

Jan 15 '07 #13
tt*******@yahoo.com wrote:
English was never my strong point.
--Richard Heathfield in comp.lang.c

Mine either.
Shouldn't this be 'Mine neither'?

Jan 15 '07 #14
santosh said:
tt*******@yahoo.com wrote:
English was never my strong point.
--Richard Heathfield in comp.lang.c

Mine either.

Shouldn't this be 'Mine neither'?
I don't know. English was never my strong point.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Jan 15 '07 #15
santosh wrote:
tt*******@yahoo.com wrote:
>>
>>English was never my strong point.
--Richard Heathfield in comp.lang.c

Mine either.

Shouldn't this be 'Mine neither'?
I suggest "Nor mine, neither yours" :-)

--
Some informative links:
<http://members.fortunecity.com/nnqweb/ (newusers)
<http://www.catb.org/~esr/faqs/smart-questions.html>
<http://www.caliburn.nl/topposting.html>
<http://www.netmeister.org/news/learn2quote.html>
<http://cfaj.freeshell.org/google/ (taming google)
Jan 15 '07 #16
In article <11**********************@v45g2000cwv.googlegroups .com>,
<tt*******@yahoo.comwrote:
> <tt*******@yahoo.comwrote:
>This post is about how to get generic modules in a C environment. The
aim is to get close to Ada generics. Using C++ is not an option. It
should all run in a simple C compiler.

[...]

Dave Vandervies wrote:
>[...]
Comment #2: What's wrong with a qsort-style interface?

It is not close to Ada, and the style only works for functions, not for
modules. (?)
If you want Ada, you know where to find it.

>I don't like function pointers.
If you want Java, you know where to find it.
Anyway, the hardware we use makes it
impossible to use function pointers. It has to do with fixed adresses
for variables that would normally be on the stack, and a very small
RAM.
In that case, it might be worth your time to write (or find) a code
generator that instantiates the generics you need for the types you need
them for, and feed the output of that to your C compiler.

Or you could use a C++ compiler and treat it as C-with-templates. If you
can find one that targets embedded platforms, it can probably even be told
to generate code as if it were C-with-templates and not full-blown C++.

Or you could find an Ada compiler and use *real* Ada generics instead
of trying to fake it in a language where it's a foreign idiom.
dave

--
Dave Vandervies dj******@csclub.uwaterloo.ca
Are you sure that Kraft's Pasteurized Process Cheese Food actually spoils?
I'm not convinced that any self-respecting microbe would be seen near it.
--Egroeg Ltreahcs in the scary devil monastery
Jan 15 '07 #17
I did something like what you want in C-Unleashed's sorting chapter
(code found here):
http://users.powernet.co.uk/eton/unl...a/896213nw.zip

You will see that I use a generic framework (using header files) and
then resolve to the appropriate type at compile time. You could call
it a poor man's template.

It's a lot easier with the appropriate plumbing, though.

Jan 15 '07 #18
tt*******@yahoo.com writes:
This post is about how to get generic modules in a C environment. The
aim is to get close to Ada generics. Using C++ is not an option. It
should all run in a simple C compiler.

When I think of a generic module, it is something that can be used
exactly as it is. The generic H-file and/or C-file, should not have to
be edited AT ALL in order to use it. If it has to be changed in just 1
line, it could possibly still have great reusability properties, but it
is not generic in the sense I mean.
I recently created a simple module for circular deques that might
fit your criteria. Here's the header file (there's no .c file).
I don't know whether it generalizes naturally to more complicated
data structures, because I've only tried it with this one so
far. It depends on a few project-specific functions, but I'm
sure you can fill in the blanks:

/* PSPP - computes sample statistics.
Copyright (C) 2007 Free Software Foundation, Inc.

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA. */

#ifndef LIBPSPP_DEQUE_H
#define LIBPSPP_DEQUE_H 1

#include <assert.h>
#include <stdbool.h>
#include <stddef.h>

#include <libpspp/compiler.h>

#include "xalloc.h"

/* Declares data and functions for a deque whose elements have
the given ELEMENT_TYPE. Instances of the deque are declared
as "struct NAME", and each function that operates on the deque
has NAME_ as a prefix. */
#define DEQUE_DECLARE(NAME, ELEMENT_TYPE) \
/* An instance of the deque. */ \
struct NAME \
{ \
size_t capacity; /* Capacity, which must be a power of 2. */ \
size_t front; /* One past the front of the queue. */ \
size_t back; /* The back of the queue. */ \
ELEMENT_TYPE *data; /* Pointer to CAPACITY elements. */ \
}; \
\
/* Initializes DEQUE as an empty deque that can store at least \
CAPACITY elements. (The actual capacity may be larger and is \
always a power of 2.) */ \
static inline void \
NAME##_init (struct NAME *deque, size_t capacity) \
{ \
deque->capacity = 1; \
while (deque->capacity < capacity) \
deque->capacity *= 2; \
deque->front = deque->back = 0; \
deque->data = xnmalloc (deque->capacity, sizeof *deque->data); \
} \
\
/* Destroys DEQUE, which must be empty. */ \
static inline void \
NAME##_destroy (struct NAME *deque) \
{ \
free (deque->data); \
} \
\
/* Returns the number of elements currently in DEQUE. */ \
static inline size_t \
NAME##_count (const struct NAME *deque) \
{ \
return deque->front - deque->back; \
} \
\
/* Returns the maximum number of elements that DEQUE can hold at \
any time. */ \
static inline size_t \
NAME##_capacity (const struct NAME *deque) \
{ \
return deque->capacity; \
} \
\
/* Returns true if DEQUE is currently empty (contains no \
elements), false otherwise. */ \
static inline bool \
NAME##_is_empty (const struct NAME *deque) \
{ \
return NAME##_count (deque) == 0; \
} \
\
/* Returns true if DEQUE is currently full (cannot take any more \
elements), false otherwise. */ \
static inline bool \
NAME##_is_full (const struct NAME *deque) \
{ \
return NAME##_count (deque) >= NAME##_capacity (deque); \
} \
\
/* Returns the element in DEQUE that is OFFSET elements from its \
front. A value 0 for OFFSET requests the element at the \
front, a value of 1 the element just behind the front, and so \
on. OFFSET must be less than the current number of elements \
in DEQUE. */ \
static inline ELEMENT_TYPE * \
NAME##_front (const struct NAME *deque, size_t offset) \
{ \
assert (NAME##_count (deque) offset); \
return &deque->data[(deque->front - offset - 1) & (deque->capacity - 1)]; \
} \
\
/* Returns the element in DEQUE that is OFFSET elements from its \
back. A value 0 for OFFSET requests the element at the back, \
a value of 1 the element just ahead of the back, and so on. \
OFFSET must be less than the current number of elements in \
DEQUE. */ \
static inline ELEMENT_TYPE * \
NAME##_back (const struct NAME *deque, size_t offset) \
{ \
assert (NAME##_count (deque) offset); \
return &deque->data[(deque->back + offset) & (deque->capacity - 1)]; \
} \
\
/* Adds and returns the address of a new element at the front of \
DEQUE, which must not be full. The caller is responsible for \
assigning a value to the returned element. */ \
static inline ELEMENT_TYPE * \
NAME##_push_front (struct NAME *deque) \
{ \
assert (!NAME##_is_full (deque)); \
return &deque->data[deque->front++ & (deque->capacity - 1)]; \
} \
\
/* Adds and returns the address of a new element at the back of \
DEQUE, which must not be full. The caller is responsible for \
assigning a value to the returned element. */ \
static inline ELEMENT_TYPE * \
NAME##_push_back (struct NAME *deque) \
{ \
assert (!NAME##_is_full (deque)); \
return &deque->data[--deque->back & (deque->capacity - 1)]; \
} \
\
/* Pops the front element off DEQUE (which must not be empty) and \
returns its address. The element may be reused the next time \
an element is pushed into DEQUE or when DEQUE is expanded. */ \
static inline ELEMENT_TYPE * \
NAME##_pop_front (struct NAME *deque) \
{ \
assert (!NAME##_is_empty (deque)); \
return &deque->data[--deque->front & (deque->capacity - 1)]; \
} \
\
/* Pops the back element off DEQUE (which must not be empty) and \
returns its address. The element may be reused the next time \
an element is pushed into DEQUE or when DEQUE is expanded. */ \
static inline ELEMENT_TYPE * \
NAME##_pop_back (struct NAME *deque) \
{ \
assert (!NAME##_is_empty (deque)); \
return &deque->data[deque->back++ & (deque->capacity - 1)]; \
} \
\
/* Expands DEQUE, doubling its capacity. */ \
static inline void \
NAME##_expand (struct NAME *deque) \
{ \
struct NAME old_deque = *deque; \
NAME##_init (deque, deque->capacity * 2); \
while (!NAME##_is_empty (&old_deque)) \
*NAME##_push_front (deque) = *NAME##_pop_back (&old_deque); \
free (old_deque.data); \
}

#endif /* libpspp/deque.h */

--
"We put [the best] Assembler programmers in a little glass case in the hallway
near the Exit sign. The sign on the case says, `In case of optimization
problem, break glass.' Meanwhile, the problem solvers are busy doing their
work in languages most appropriate to the job at hand." --Richard Riehle
Jan 15 '07 #19

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

27
by: Bernardo Heynemann | last post by:
How can I use Generics? How can I use C# 2.0? I already have VS.NET 2003 Enterprise Edition and still can´t use generics... I´m trying to make a generic collection myCollection<vartype> and...
2
by: Mr.Tickle | last post by:
So whats the deal here regarding Generics in the 2004 release and templates currently in C++?
23
by: Luc Vaillant | last post by:
I need to initialise a typed parameter depending of its type in a generic class. I have tried to use the C++ template form as follow, but it doesn't work. It seems to be a limitation of generics...
12
by: Michael S | last post by:
Why do people spend so much time writing complex generic types? for fun? to learn? for use? I think of generics like I do about operator overloading. Great to have as a language-feature, as...
5
by: anders.forsgren | last post by:
This is a common problem with generics, but I hope someone has found the best way of solving it. I have these classes: "Fruit" which is a baseclass, and "Apple" which is derived. Further I have...
11
by: herpers | last post by:
Hello, I probably don't see the obvious, but maybe you can help me out of this mess. The following is my problem: I created two classes NormDistribution and DiscDistribution. Both classes...
9
by: sloan | last post by:
I'm not the sharpest knife in the drawer, but not a dummy either. I'm looking for a good book which goes over Generics in great detail. and to have as a reference book on my shelf. Personal...
1
by: Vladimir Shiryaev | last post by:
Hello! Exception handling in generics seems to be a bit inconsistent to me. Imagine, I have "MyOwnException" class derived from "ApplicationException". I also have two classes...
7
by: SpotNet | last post by:
Hello NewsGroup, Reading up on Generics in the .NET Framework 2.0 using C# 2005 (SP1), I have a question on the application of Generics. Knowingly, Generic classes are contained in the...
13
by: rkausch | last post by:
Hello everyone, I'm writing because I'm frustrated with the implementation of C#'s generics, and need a workaround. I come from a Java background, and am currently writing a portion of an...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.