I'm trying to use the GNU Scientific Library and am having trouble understanding its documentation. Here's the sample program from the page on gsl_rng_env_setup:
#include <stdio.h>
#include <gsl/gsl_rng.h>
gsl_rng * r; /* global generator */
int
main (void)
{
const gsl_rng_type * T;
gsl_rng_env_setup();
T = gsl_rng_default;
r = gsl_rng_alloc (T);
printf ("generator type: %s\n", gsl_rng_name (r));
printf ("seed = %lu\n", gsl_rng_default_seed);
printf ("first value = %lu\n", gsl_rng_get (r));
gsl_rng_free (r);
return 0;
}
My problems start with the third line, gsl_rng * r. This is clearly not multiplication (neither variable defined yet), so it must be pointer notation. However from the C++ tutorial on pointers, I would expect something like gsl_rng = *r, which would take the value of r and store that as gsl_rng. My guess is that gsl_rng isn't a variable, but some GNU Scientific library command; however I don't understand the documentation page for it also: this command is clearly not of the form gsl_rng * gsl_rng_alloc (const gsl_rng_type * T) - even if r = gsl_rng_alloc, this command doesn't have brackets.
It doesn't help that a bit further down we have the line const gsl_rng_type * T which is of the same form but also clearly does something different. This line seems to be defining gsl_rng_type as a constant, and assigning it the value of *T - but this is missing an assignment operator. Yet T must be a variable, since a few lines later it's assigned the value of gsl_rng_default ...
My problems seem to be extremely basic which is troubling. Can anyone point me in the right direction?
gsl_rng is a type. The statement gsl_rng * r; declares a global variable named r with type pointer to gsl_rng.
Later, there is this line r = gsl_rng_alloc (T);, which assigns some value to that declared variable.
This is basic C++, so maybe you should start with some good book, if you want to understand such code.
The trick is to remember that there are different kinds of random number generators. Each one is its' own class. The gsl_rng_alloc method will create a random number generator object for you but wants to know what class to use. You tell it what class to use by passing the class. Then the method uses that class to instantiate an object for you. It returns to you a pointer to the object that it created for you.
Related
I am learning C++ using C++ Primer 5th edition. In particular, i read about void*. There it is written that:
We cannot use a void* to operate on the object it addresses—we don’t know that object’s type, and the type determines what operations we can perform on that object.
void*: Pointer type that can point to any nonconst type. Such pointers may not
be dereferenced.
My question is that if we're not allowed to use a void* to operate on the object it addressess then why do we need a void*. Also, i am not sure if the above quoted statement from C++ Primer is technically correct because i am not able to understand what it is conveying. Maybe some examples can help me understand what the author meant when he said that "we cannot use a void* to operate on the object it addresses". So can someone please provide some example to clarify what the author meant and whether he is correct or incorrect in saying the above statement.
My question is that if we're not allowed to use a void* to operate on the object it addressess then why do we need a void*
It's indeed quite rare to need void* in C++. It's more common in C.
But where it's useful is type-erasure. For example, try to store an object of any type in a variable, determining the type at runtime. You'll find that hiding the type becomes essential to achieve that task.
What you may be missing is that it is possible to convert the void* back to the typed pointer afterwards (or in special cases, you can reinterpret as another pointer type), which allows you to operate on the object.
Maybe some examples can help me understand what the author meant when he said that "we cannot use a void* to operate on the object it addresses"
Example:
int i;
int* int_ptr = &i;
void* void_ptr = &i;
*int_ptr = 42; // OK
*void_ptr = 42; // ill-formed
As the example demonstrates, we cannot modify the pointed int object through the pointer to void.
so since a void* has no size(as written in the answer by PMF)
Their answer is misleading or you've misunderstood. The pointer has a size. But since there is no information about the type of the pointed object, the size of the pointed object is unknown. In a way, that's part of why it can point to an object of any size.
so how can a int* on the right hand side be implicitly converted to a void*
All pointers to objects can implicitly be converted to void* because the language rules say so.
Yes, the author is right.
A pointer of type void* cannot be dereferenced, because it has no size1. The compiler would not know how much data he needs to get from that address if you try to access it:
void* myData = std::malloc(1000); // Allocate some memory (note that the return type of malloc() is void*)
int value = *myData; // Error, can't dereference
int field = myData->myField; // Error, a void pointer obviously has no fields
The first example fails because the compiler doesn't know how much data to get. We need to tell it the size of the data to get:
int value = *(int*)myData; // Now fine, we have casted the pointer to int*
int value = *(char*)myData; // Fine too, but NOT the same as above!
or, to be more in the C++-world:
int value = *static_cast<int*>(myData);
int value = *static_cast<char*>(myData);
The two examples return a different result, because the first gets an integer (32 bit on most systems) from the target address, while the second only gets a single byte and then moves that to a larger variable.
The reason why the use of void* is sometimes still useful is when the type of data doesn't matter much, like when just copying stuff around. Methods such as memset or memcpy take void* parameters, since they don't care about the actual structure of the data (but they need to be given the size explicitly). When working in C++ (as opposed to C) you'll not use these very often, though.
1 "No size" applies to the size of the destination object, not the size of the variable containing the pointer. sizeof(void*) is perfectly valid and returns, the size of a pointer variable. This is always equal to any other pointer size, so sizeof(void*)==sizeof(int*)==sizeof(MyClass*) is always true (for 99% of today's compilers at least). The type of the pointer however defines the size of the element it points to. And that is required for the compiler so he knows how much data he needs to get, or, when used with + or -, how much to add or subtract to get the address of the next or previous elements.
void * is basically a catch-all type. Any pointer type can be implicitly cast to void * without getting any errors. As such, it is mostly used in low level data manipulations, where all that matters is the data that some memory block contains, rather than what the data represents. On the flip side, when you have a void * pointer, it is impossible to determine directly which type it was originally. That's why you can't operate on the object it addresses.
if we try something like
typedef struct foo {
int key;
int value;
} t_foo;
void try_fill_with_zero(void *destination) {
destination->key = 0;
destination->value = 0;
}
int main() {
t_foo *foo_instance = malloc(sizeof(t_foo));
try_fill_with_zero(foo_instance, sizeof(t_foo));
}
we will get a compilation error because it is impossible to determine what type void *destination was, as soon as the address gets into try_fill_with_zero. That's an example of being unable to "use a void* to operate on the object it addresses"
Typically you will see something like this:
typedef struct foo {
int key;
int value;
} t_foo;
void init_with_zero(void *destination, size_t bytes) {
unsigned char *to_fill = (unsigned char *)destination;
for (int i = 0; i < bytes; i++) {
to_fill[i] = 0;
}
}
int main() {
t_foo *foo_instance = malloc(sizeof(t_foo));
int test_int;
init_with_zero(foo_instance, sizeof(t_foo));
init_with_zero(&test_int, sizeof(int));
}
Here we can operate on the memory that we pass to init_with_zero represented as bytes.
You can think of void * as representing missing knowledge about the associated type of the data at this address. You may still cast it to something else and then dereference it, if you know what is behind it. Example:
int n = 5;
void * p = (void *) &n;
At this point, p we have lost the type information for p and thus, the compiler does not know what to do with it. But if you know this p is an address to an integer, then you can use that information:
int * q = (int *) p;
int m = *q;
And m will be equal to n.
void is not a type like any other. There is no object of type void. Hence, there exists no way of operating on such pointers.
This is one of my favourite kind of questions because at first I was also so confused about void pointers.
Like the rest of the Answers above void * refers to a generic type of data.
Being a void pointer you must understand that it only holds the address of some kind of data or object.
No other information about the object itself, at first you are asking yourself why do you even need this if it's only able to hold an address. That's because you can still cast your pointer to a more specific kind of data, and that's the real power.
Making generic functions that works with all kind of data.
And to be more clear let's say you want to implement generic sorting algorithm.
The sorting algorithm has basically 2 steps:
The algorithm itself.
The comparation between the objects.
Here we will also talk about pointer functions.
Let's take for example qsort built in function
void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void *, const void*))
We see that it takes the next parameters:
base − This is the pointer to the first element of the array to be sorted.
nitems − This is the number of elements in the array pointed by base.
size − This is the size in bytes of each element in the array.
compar − This is the function that compares two elements.
And based on the article that I referenced above we can do something like this:
int values[] = { 88, 56, 100, 2, 25 };
int cmpfunc (const void * a, const void * b) {
return ( *(int*)a - *(int*)b );
}
int main () {
int n;
printf("Before sorting the list is: \n");
for( n = 0 ; n < 5; n++ ) {
printf("%d ", values[n]);
}
qsort(values, 5, sizeof(int), cmpfunc);
printf("\nAfter sorting the list is: \n");
for( n = 0 ; n < 5; n++ ) {
printf("%d ", values[n]);
}
return(0);
}
Where you can define your own custom compare function that can match any kind of data, there can be even a more complex data structure like a class instance of some kind of object you just define. Let's say a Person class, that has a field age and you want to sort all Persons by age.
And that's one example where you can use void * , you can abstract this and create other use cases based on this example.
It is true that is a C example, but I think, being something that appeared in C can make more sense of the real usage of void *. If you can understand what you can do with void * you are good to go.
For C++ you can also check templates, templates can let you achieve a generic type for your functions / objects.
In A Tour of C++ by Bjarne Stroustrup, some advice is listed at the end of each chapter. At the end of the first chapter one of them reads:
Avoid ‘‘magic constants;’’ use symbolic constants;
What are magic and symbolic constants?
somethingElse = something * 1440; // a magic constant
somethingElse = something * TWIPS_PER_INCH; // a symbolic one
The first is an example of the magic constant, it conveys no other information other than its value.
The latter is far more useful since the intent is clear.
Using symbolic constant also helps a great deal if you have multiple things with the same value:
static const int TWIPS_PER_INCH = 1440;
static const int SECTORS_PER_FLOPPY = 1440; // showing my age here :-)
That way, if one of them changes, you can easily identify which single 1440 in the code has to change. With magic 1440s scattered throughout the code, you have to change it in multiple places and figure out which are the twips and which are the sectors.
A magic constant would be a numeric value that you just type into some code with no explanation about why it is there. Coming up with a good example is challenging. But let's try this:
float areaOfCircle(float radius) {
return radius * radius * 3.14159
}
Here I've used a "magic constant" of 3.14159 without any explanation of where it comes from. It would be better style to say
const float pi = 3.14159
float areaOfCircle(float radius) {
return radius * radius * pi;
}
Here I've given the person reading the code some idea about where the constant came from and why it was used... it didn't seem to "magically" appear out of nowhere.
Magic:
int DeepThought() { return 42; }
Symbolic:
const int TheAnswerToTheUltimateQuestionOfLifeTheUniverseAndEverything = 42;
int DeepThought() { return TheAnswerToTheUltimateQuestionOfLifeTheUniverseAndEverything; }
Let's say that we want to declare three integers, p, q, and r. Best practice is to initialize them to 0. The C way of doing this is:
int p, q, r;
p = q = r = 0;
The C++ way of doing this is
int p(0), q(0), r(0);
In C, things are nice and tight; 0 is only used once. In contrast, the C++ call requires 0 to be repeated three times--once for each variable. A bit verbose.
Is there a more concise way of initializing variables using the C++ method, or is the initial value required for each variable declaration?
Also, any problem mixing the C-style initialization with C++ code? Thx :^)
EDIT: Fixed code to compile properly. Now, it takes two lines to declare and initialize the variables, so the question isn't very good, but I will leave it here for posterity. Hopefully helps someone.
Best practice is to initialize them to 0.
This may be even harmful, as it would silence the compiler's protection. Consider following code:
int p, q, r;
p = q = r = 0;
// ...
p = FIRST_INDEX;
r = LAST_INDEX; // ups, we forget to initialize q with some real value
// ...
doSomething(p, q, r);
Normally, you will get a warning like:
warning: 'q' is used uninitialized in this function [-Wuninitialized]
but since the q is already intialized, the compiler thinks that is fine.
Intermixing declarations with code
If you have C++ or at least C99-conformant compiler, then one may argue, that code could be designed better, by moving variables' declarations closest to their first usage:
// some executable code
int p = FIRST_INDEX;
int q = LAST_INDEX;
int r = getSampleCoefficient();
doSomething(p, q, r);
This way, the issue presented in previous example may be avoided completely, since there is no gap between declarations and actual code.
You may use p = q = r = 0; in C++, it's just matter of coding style.
I am interested in Judy Arrays and try to use it. But i had unable to do any useful thing using it. Every time it gives me casting errors.. Sample c++ code and the error given below.
#include "Judy.h"
#include <iostream>
using namespace std;
int main()
{
int Rc_int; // return code - integer
Word_t Rc_word; // return code - unsigned word
Word_t Index = 12, Index1 = 34, Index2 = 55, Nth;
Word_t PValue; // pointer to return value
//Pvoid_t PJLArray = NULL; // initialize JudyL array
Pvoid_t JudyArray = NULL;
char String[100];
PWord_t _PValue;
JSLI( JudyArray, _PValue, (uint8_t *) String);
return(0);
} // main()
This gives me the error
m.cpp: In function ‘int main()’:
m.cpp:19: error: invalid conversion from ‘long unsigned int**’ to ‘void**’
m.cpp:19: error: initializing argument 1 of ‘void** JudySLIns(void**, const uint8_t*, J_UDY_ERROR_STRUCT*)’
Please anyone help me to figure out what is the error what i'm doing..
Thanks
According to the documentation, you have the _PValue and JudyArray parameters reversed. Make your call look like this:
JSLI( _PValue, JudyArray, (uint8_t *) String);
Also, try not compiling it as C++ code. So far, your test uses no C++ features. I bet it will compile as C code. It looks like JudyArray relies on the fact that C will do certain kinds of implicit conversions between void * and other pointer types.
If this is the case, I'm not sure what to do about it. The error messages you're getting tell me that JSLI is a macro. In order to fix the error message you have in the comments on this answer, you'd have to reach inside the macro and add a typecast.
These kinds of implicit conversions are allowed in C because otherwise using malloc would always require ugly casts. C++ purposely disallows them because the semantics of new make the requirement that the result of malloc be cast to the correct type unimportant.
I don't think this library can be used effectively in C++ for this reason.
It seems that, you pass JudySLIns(void**, const uint8_t*, J_UDY_ERROR_STRUCT*) a wrong parameter, the first one, you'b better check it!
For integer keys there is a C++ wrapper at http://judyhash.sourceforge.net/
Any ideas for this typecasting problem?
Here's what I am trying to do. This is not the actual code:
LinkedList* angles;
double dblangle;
dblangle = (some function for angle calculation returning double value);
(double*)LinkedListCurrent(angles) = &double;
I hope you get the idea. The last line is causing the problem. Initially angles is void* type so I have to first convert it to double*.
You use the unary * operator to dereference a pointer. Dereferencing a pointer means extracting the value pointed to, to get a value of the original type.
// Create a double value
double foo = 1.0;
// Create a pointer to that value
double *bar = &foo;
// Extract the value from that pointer
double baz = *bar;
edit 2: (deleted edit 1 as it was not relevant to your actual question, but was based on a miscommunication)
From your clarification, it looks like you are wondering how to set a value pointed to by a pointer that has been cast from a void * to a double *. In order to do this, we need to use the unary * on the left hand side of the assignment, in order to indicate that we want to write to the location pointed to by the pointer.
// Get a void * pointing to our double value.
void *vp = &foo;
// Now, set foo by manipulating vp. We need to cast it to a double *, and
// then dereference it using the * operator.
*(double *)vp = 2.0;
// And get the value. Again, we need to cast it, and dereference it.
printf("%F\n", *(double *)vp);
So, I'm assuming that your LinkedListCurrent is returning a void * pointing to some element in the linked list that you would like to update. In that case, you would need to do the following:
*(double*)LinkedListCurrent(angles) = dbangle;
This updated the value pointed to by the pointer returned from LinkedListCurrent to be equal to dbangle. I believe that is what you are trying to do.
If you are trying to update the pointer returned by LinkedListCurrent, you can't do that. The pointer has been copied into a temporary location for returning from the function. If you need to return a pointer that you can update, you would have to return a pointer to a pointer, and update the inner one.
My explanation above is based on what I believe you are trying to do, based on the example snippet you posted and some guesses I've made about the interface. If you want a better explanation, or if one of my assumptions was bad, you might want to try posting some actual code, any error messages you are getting, and a more detailed explanation of what you are trying to do. Showing the interface to the linked list data type would help to provide some context for what your question is about.
edit 3: As pointed out in the comments, you probably shouldn't be casting here anyhow; casts should be used as little as possible. You generally should use templated collection types, so your compiler can actually do typechecking for you. If you need to store heterogenous types in the same structure, they should generally share a superclass and have virtual methods to perform operations on them, and use dynamic_cast if you really need to cast a value to a particular type (as dynamic_cast can check at runtime that the type is correct).
why on earth would you want to use a memory address as a floating point number?
if you meant dereference:
double d = 1.0; // create a double variable with value 1.0
double *dp = &d; // store its address in a pointer
double e = *dp; // copy the value pointed at to another variable
Note this line:
(double*)LinkedListCurrent(angles) = &double;
where you've written &double, it i think should be &dbangle. To improve readability, I would write:
((double*)LinkedListCurrent(angles)) = &dbangle;
However, you should not do this type of conversion as others mentioned.
Use a union. If you want the store two variables in one memory location (but not at the same time), you don't have to pretend that one is the other.
union double_and_ptr {
double d;
double *p;
};
double_and_ptr x, y;
x.d = 0.1;
y.p = &x.d; // store a pointer in the same place as a double
y.d = x.d * 1.2; // store a double in the same place as a ptr
Use reinterpret_cast.
double foo = 3.0;
double* pfoo = &foo;
double bar = reinterpret_cast<double>(pfoo);
In answer to this:
I want to do the opposite of what you have done here. I want to copy the value from the pointer to the d floating point number. How can I do that?
You would do something like this:
// declare a pointer to a double
double *pointer_to_double;
// declare a double
double my_double = 0.0;
// use the indirection operator (*) to dereference the pointer and get the value
// that it's pointing to.
my_double = *pointer_to_double;
This might be done like so in a real program:
void print_chance_of_snow(double *chance)
{
double d = *chance;
d = d * 100; // convert to a percentage
printf("Chance of snow is: %.2f%%\n", d);
}
int main(int argc, char *argv[])
{
double chance_of_snow = 0.45;
print_chance_of_snow(&chance_of_snow);
}