What does the OpenGL command suffix 'v' represent? - opengl

Generally, OpenGL commands has a suffix like 'i', 'f', 'v', etc. I know it's specifying the parameter type.
void glGetBooleanv(GLenum pname, GLboolean *params);
Why is 'v' used for a pointer and what word does it represent?

From the standard:
A final v character, if present, indicates that the command takes a pointer to an array (a vector) of values rather than a series of individual arguments
– OpenGL 4.5 Specification, Page 11

Related

Is there a function for moving the contents of a char array a certain amount of addresses back in C++?

I have the following code for Arduino (C++). This is for a checksum consisting of 2 characters forming a base 16 value between 0 and 255. It takes int outputCheckSum and converts it to char outputCheckSumHex[3].
itoa (outputCheckSum, outputCheckSumHex, 16)
if (outputCheckSum < 16) { //Adds a 0 if CS has fewer than 2 numbers
outputCheckSumHex[1] = outputCheckSumHex[0];
outputCheckSumHex[0] = '0';
}
Since the output of itoa would be "X" instead of "0X" in the event of X having fewer than 2 characters, the last 3 lines are to move the characters one step back.
I now have plans to scale this up to a CS of 8 characters, and I was wondering whether there exists a function in C++ that can achieve that before I start writing more code. Please let me know if more information is required.
You should be able to use memmove, it's one of the legacy C functions rather than C++ but it's available in the latter (in cstring header) and handles overlapping memory correctly, unlike memcpy.
So, for example, you could use:
char buff[5] = {'a', 'b', 'c', '.', '.'};
memmove(&(buff[2]), &(buff[0], 3);
// Now it's {'a', 'b', 'a', 'b', 'c'} and you can replace the first two characters.
Alternatively, you could use std::copy from the algorithm header but, for something this basic, memmove should be fine.
You can use memmove in <cstring> for this. It does not check for terminating null characters, but instead copies num bytes (third argument) and works with overlapping regions as well.
void* memmove(void* destination, const void* source, size_t num);

Why do "strings", i.e. character arrays, have a null-terminating element, whereas integer arrays don't?

From what I understand, character arrays in C/C++ have a null-terminating character for the purpose of denoting an off-the-end element of that array, while integer arrays don't; they have some internal mechanism that is hidden from the user, but they obviously know their own size since the user can do sizeof(myArray)/sizeof(int) (Is that technically a hack?). Wouldn't it make sense for an integer array to have some null-terminating int -- call it i or something?
Why is this? It has never made any sense to me.
Because, in C, strings are not the same as character arrays, they exist at a level above arrays in much the same way as a linked list exists at a level above structures.
This is an example of a string:
"pax is great"
This is an example of a character array:
{ 'p', 'a', 'x' }
This is an example of a character array that just happens to be equivalent to a string:
{ 'p', 'a', 'x', '\0' }
In other words, C string are built on top of character arrays.
If you look at it another way, neither integer arrays nor "real" character arrays (like {'a', 'b', 'c'} for example) have a terminating character.
You can quite easily do the same thing (have a terminator) with an integer array of people's ages, using -1 (or any negative number) as the terminator.
The only difference is that you'll write your own code to handle it rather than using code helpfully provided in the C standard library, things like:
size_t agelen (int *ages) {
size_t len = 0;
while (*ages++ >= 0)
len++;
return len;
}
int *agecpy (int *src, int *dst) {
int *d = dst;
while (*s >= 0)
*d++ = *src++;
*dst = -1;
return dst;
}
Because string does not exists in c.
Because the null terminator is there to mark the end of the input and it doesn't have to be the length of the given array.
This is by convention, treating null as a non-character. Unlike other major system software languages of then e.g. PL/1 which had a leading integer to denote the length of a variable length character string, C was designed to treat strings as simply character arrays and did not want the overhead and in particular any portability issues (such as sizeof int) nor any limitations (what about very long strings). The convention has stuck because it worked out rather well.
To denote end of an int array as you have suggested would require a non-Int marker. That could be rather difficult to arrange. And sizeof an int array as you are figuring out is merely taking advantage of your knowledge of *alloc - there is absolutely nothing in C to prevent you from cobbling together an "array" by clever management of allocated memory. Modern compilers of course contain many convenience checks on wayward code and someone with better knowledge of compilers could clarify/rectify my comments here. C++ Vector contains an explicit knowledge of array capacity, for example.
A lot of places you can see a different Field Separator FS character used to separate out strings. E.g., CSV. But if you were to do that, you will need to write you own std libraries - thousands and thousands of lines of good, tested code.
A C-Style string is a collection of characters terminated by '\0'. It is not an array.
The collection can be indexed like an array.
Because the length of the collection can vary, the length must be determined by counting the number of characters in the collection.
A convenient representation is an array because an array is also a collection.
One difference is that an array is a fixed sized data structure. The collection of characters may not be a fixed size; for example, it can be concatenated.
If you think about the problem of how to represent strings, you have two choices: 1) store a count of letters followed by the letters or 2) store the letters followed by some unique special character used as an end of string marker.
End of string marker is more flexible - longer strings possible, easier to use, etc.
BTW you can have terminator on an int array if you want... Nothing stopping you saying that a -1 for example means the end if the list, as long as you are sure that the -1 is unique.

Is this the correct syntax for an array of pointers to size-3 character arrays?

I'm trying to make my own version of an "Autocorrect" program that checks for words that are similar to a given word. To accomplish this, I need to look at distances between letters on a standard keyboard, so that I have a metric for how "close" a word is to another word.
In my program I've started to write an array
const char[3]* KEY_DISTS[] = { "aa0", "ab5", "ba5", "ac3", "ca3", "ad2", "da2" ,... };
which is supposed to mean "The distance between 'a' and 'a' is 0, the distance between 'a' and 'b' is 5, the distance between 'b' and 'a' is 5, " etcetera.
That information I will next put in a map that maps pairs of characters to integers, but I'm wondering whether it's written correctly so far and whether you have any suggestions for me.
const char[3]* KEY_DISTS[]
should mean "A constant array of pointers to character arrays of size 3", right?
The declaration matching the title would be:
const char (*arr[])[4] = { &"aa0" };
Note that "arr" is an array of four chars (it includes terminating '\0') and that you need to take the address of string literal (which are lvalues and have static storage duration, so this is fine).
Sounds like you could have a 2D array instead:
const char arr[][4] = { "aa0" };

Storing a string in an array of chars without the null character

I'm reading the C++ Primer Plus by Stephen Prata. He gives this example:
char dog[8] = { 'b', 'e', 'a', 'u', 'x', ' ', 'I', 'I'}; // not a string!
char cat[8] = {'f', 'a', 't', 'e', 's', 's', 'a', '\0'}; // a string!
with the comment that:
Both of these arrays are arrays of char, but only the second is a string.The null character
plays a fundamental role in C-style strings. For example, C++ has many functions that
handle strings, including those used by cout.They all work by processing a string character-
by-character until they reach the null character. If you ask cout to display a nice string
like cat in the preceding example, it displays the first seven characters, detects the null
character, and stops. But if you are ungracious enough to tell cout to display the dog array
from the preceding example, which is not a string, cout prints the eight letters in the
array and then keeps marching through memory byte-by-byte, interpreting each byte as a
character to print, until it reaches a null character. Because null characters, which really are
bytes set to zero, tend to be common in memory, the damage is usually contained quickly;
nonetheless, you should not treat nonstring character arrays as strings.
Now, if a declare my variables global, like this:
#include <iostream>
using namespace std;
char a[8] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
char b[8] = {'1', '2', '3', '4', '5', '6', '7', '8'};
int main(void)
{
cout << a << endl;
cout << b << endl;
return 0;
}
the output will be:
abcdefgh12345678
12345678
So, indeed, the cout "keeps marching through memory byte-by-byte" but only to the end of the second character array. The same thing happens with any combination of char array. I'm thinking that all the other addresses are initialized to 0 and that's why the cout stop. Is this true? If I do something like:
for (int i = 0; i < 100; ++i)
{
cout << *(&a + i) << endl;
}
I'm getting mostly empty space at output (like 95%, perhaps), but not everywhere.
If, however, i declare my char arrays a little bit shorter, like:
char a[3] = {'a', 'b', 'c'};
char b[3] = {'1', '2', '3'};
keeping all other things the same, I'm getting the following output:
abc
123
Now the cout doesn't even get past the first char array, not to mention the second. Why is this happening? I've checked the memory addresses and they are sequential, just like in the first scenario. For example,
cout << &a << endl;
cout << &b << endl;
gives
003B903C
003B9040
Why is the behavior different in this case? Why doesn't it read beyond the first char array?
And, lastly if I do declare my variables inside main, then I do get the behavior suggested by Prata, namely, a lot of junk gets printed before, somewhere a null character is reached.
I'm guessing that in the first case, the char array is declared on the heap and that this is initialized to 0 (but not everywhere, why?) and cout behaves differently based on the length of the char array (why?)
I'm using Visual Studio 2010 for these examples.
It looks like your C++ compiler is allocating space in 4-byte chunks, so that every object has an address that is a multiple of 4 (the hex addresses in your dump are divisible by 4). Compilers like to do this because they like to make sure larger datatypes such as intand float (4 bytes wide) are aligned to 4-byte boundaries. Compilers like to do this because some kinds of computer hardware take longer to load/move/store unaligned int and float values.
In your first example, each array need 8 bytes of memory - a char fills a single byte - so the compiler allocates exactly 8 bytes. In the second example each array is 3 bytes, so the compiler allocates 4 bytes, fills the first 3 bytes with your data, and leaves the 4th byte unused.
Now in this second case it appears the unused byte was filled with a null which explains why cout stopped at the end of the string. But as others have pointed out, you cannot depend on unused bytes to be initialized to any particular value, so the behaviour of the program cannot be guaranteed.
If you change your sample arrays to have 4 bytes the program will behave as in the first example.
The contents of memory out of bounds is indeterminate. Accessing memory you do not own, even just for reading, leads to undefined behavior.
Its an undefined behaviour, you cannot say what can happen.
Try on some other system you may get different output.
The answer to your question is that it is an Undefined Behaviour and its output cannot be explained.
In addition to above explanantion, in your particular case, you have declared array globally.
Therefore in your second example a \0 is appended in the fourth byte of four-byte boundary as explained by Peter Raynham.
The '\0' is just a solution to tell how long is a string. Lets say you know how long it is by storing a value before the string.
But your case is when you intentionally leave it out the functions and normally your code as well will keep searching for the delimiter ( which is a null character ).
It is undefined what is behind the bounds of a specified memory it greatly varies.
In Mingw in debug mode with gdb its usually zeroed out, without gdb its just junk... altho this is just my experience.
For the locally declared variables they are usually on the stack so what you are reading, is probably your call stack.

C/C++: Inherent ambiguity of "\xNNN" format in literal strings

Consider these two strings:
wchar_t* x = L"xy\x588xla";
wchar_t* y = L"xy\x588bla";
Upon reading this you would expect that both string literals are the same except one character - an 'x' instead of a 'b'.
It turns out that this is not the case. The first string compiles to:
y = {'x', 'y', 0x588, 'x', 'l', 'a' }
and the second is actually:
x = {'x', 'y', 0x588b, 'l', 'a' }
They are not even the same length!
Yes, the 'b' is eaten up by the hex representation ('\xNNN') character.
At the very least, this could cause confusion and subtle bugs for in hand-written strings (you could argue that unicode strings don't belong in the code body)
But the more serious problem, and the one I am facing, is in auto-generated code. There just doesn't seem to be any way to express this: {'x', 'y', 0x588, 'b', 'l', 'a' } as a literal string without resorting to writing the entire string in hex representation, which is wasteful and unreadable.
Any idea of a way around this?
What's the sense in the language behaving like this?
A simple way is to use compile time string literal concatenation, thus:
wchar_t const* y = L"xy\x588" L"bla";