473,734 Members | 2,693 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Initialization of a const matrix implemented as pointer-to-pointer

Subject: Initialization of a const matrix implemented as pointer-to-pointer

Hello everyone.

I've got the following matrix definition in a source file

static const char **a;

I need it to be initialized as an array of strings, something like

static const char **a = {"Alpha", "Beta", Charlie"};

I know the number of strings and their maximum length, but I can't use a
stack-allocated matrix for compatibility reasons with another piece of
code, which simply defines a

char** strings

to which the matrix has to be assigned to.

I thought I could write a static const declaration for each string

static const str1[MAX_LENGTH] ="Alpha"

and then declare the matrix as

static const char* a[NUM_OF_STRINGS] = {str1,str2,...}

would it be correct?

thanks for your attention

AT

Sep 10 '08 #1
17 2736
Andrea Taverna (Tavs) wrote:
Subject: Initialization of a const matrix implemented as pointer-to-pointer

Hello everyone.

I've got the following matrix definition in a source file

static const char **a;

I need it to be initialized as an array of strings, something like

static const char **a = {"Alpha", "Beta", Charlie"};

I know the number of strings and their maximum length, but I can't use a
stack-allocated matrix for compatibility reasons with another piece of
code, which simply defines a

char** strings

to which the matrix has to be assigned to.

I thought I could write a static const declaration for each string

static const str1[MAX_LENGTH] ="Alpha"

and then declare the matrix as

static const char* a[NUM_OF_STRINGS] = {str1,str2,...}

would it be correct?

thanks for your attention
Looks OK to me.
You don't need NUM_OF_STRINGS.
And if you have the strings available to write
static const str1[MAX_LENGTH] ="Alpha";
then you don't need str1 either.

How about
static const char *a[] = {"Alpha", "Beta", Charlie"};
?

/* BEGIN new.c output */

Alpha
Beta
Charlie

/* END new.c output */

/* BEGIN new.c */

#include <stdio.h>

int main(void)
{
static const char *a[] = {"Alpha", "Beta", "Charlie"};
size_t index;

puts("/* BEGIN new.c output */\n");
for (index = 0; index != sizeof a / sizeof *a; ++index) {
puts(a[index]);
}
puts("\n/* END new.c output */");
return 0;
}

/* END new.c */

--
pete
Sep 10 '08 #2
On Wed, 10 Sep 2008 13:57:47 +0200, "Andrea Taverna (Tavs)"
<a.****@libero. itwrote:
>Subject: Initialization of a const matrix implemented as pointer-to-pointer

Hello everyone.

I've got the following matrix definition in a source file

static const char **a;
In this case, sizeof a will probably be 4 or 8.
>
I need it to be initialized as an array of strings, something like

static const char **a = {"Alpha", "Beta", Charlie"};

I know the number of strings and their maximum length, but I can't use a
stack-allocated matrix for compatibility reasons with another piece of
code, which simply defines a

char** strings
>
to which the matrix has to be assigned to.
There should be no problem "assigning the array" to this pointer.
>
I thought I could write a static const declaration for each string

static const str1[MAX_LENGTH] ="Alpha"

and then declare the matrix as

static const char* a[NUM_OF_STRINGS] = {str1,str2,...}
If NUM_OF_STRINGS is 3 (to be consistent with your example), sizeof a
will probably be 12 or 24.
>
would it be correct?
It depends on how you plan to use a.

In the first example, is a true pointer. It can appear on the left
side of the assignment operator. In the second, a is an array which
cannot appear there. However, in both cases, a can appear on the
right of the assignment operator.

If all you want is a variable name that can be subscripted to evaluate
to different strings, then the second will work. If you delete the
"static", it will become a "stack allocated matrix" (technically an
automatic array of char*). When the array name "a" appears in an
expression context other than as the operand of sizeof and &, it will
be converted to the address of a[0] with type "pointer to type of
a[0]". Since a is an array of char*, a[0] is the first char* in the
array. The type "pointer to type of a[0]" is simply "pointer to
char*" also known as char**. Therefore you can assign the array name
"a" to the variable "strings" in the other code.

On the other hand, if you need a true pointer that can be reassigned
to point to different sets of strings, then something of the form:

const astr1[] = "Alpha";
...
const astrx[] = "Omega";
const bstr1[] = "Alef";
...
const bstrx[] = "Tav";
const char* A[] = {astr1,...,astr x};
const char* B[] = {bstr1,...,bstr x};
const char **a = A;
...
a = B;
and anywhere in your code you can say
strings = a;

--
Remove del for email
Sep 10 '08 #3
Barry Schwarz ha scritto:
In this case, sizeof a will probably be 4 or 8.
>I need it to be initialized as an array of strings, something like

static const char **a = {"Alpha", "Beta", Charlie"};

I know the number of strings and their maximum length, but I can't use a
stack-allocated matrix for compatibility reasons with another piece of
code, which simply defines a

char** strings
> to which the matrix has to be assigned to.

There should be no problem "assigning the array" to this pointer.
Actually there is. GCC warns that they're not compatible
On the other hand, if you need a true pointer that can be reassigned
to point to different sets of strings, then something of the form:

const astr1[] = "Alpha";
...
const astrx[] = "Omega";
const bstr1[] = "Alef";
...
const bstrx[] = "Tav";
const char* A[] = {astr1,...,astr x};
const char* B[] = {bstr1,...,bstr x};
const char **a = A;
...
a = B;
and anywhere in your code you can say
strings = a;
that's precisely what I'm going to do.

Thanks

AT
Sep 10 '08 #4
Ok, I've tried both ways, Barry's and Pete's. GCC still wars about
compatibility, but it behaves correctly at run time, so the problem is set.

Thank you :D

AT
Sep 10 '08 #5
Andrea Taverna (Tavs) wrote:
Barry Schwarz ha scritto:
In this case, sizeof a will probably be 4 or 8.
I need it to be initialized as an array of strings, something like

static const char **a = {"Alpha", "Beta", Charlie"};

I know the number of strings and their maximum length, but I can't use a
stack-allocated matrix for compatibility reasons with another piece of
code, which simply defines a

char** strings
to which the matrix has to be assigned to.
There should be no problem "assigning the array" to this pointer.

Actually there is. GCC warns that they're not compatible
That's because the second declaration should be

const char** strings;

If you don't have the power to change the declaration of 'strings',
check the documentation of the other piece of code very carefully. Is
that code going to attempt to write to those strings? If not, then it
was a mistake on the designer's part to declare "strings" without
using const. However, it's a mistake you can deal with by simply use a
cast:

strings = (char**)a;

However, it if will be writing to the strings, then this is not an
appropriate approach; the memory allocated for string literals is not
necessarily writable. In that case, follow the example given below,
but remove the word "const" wherever it appears:
On the other hand, if you need a true pointer that can be reassigned
to point to different sets of strings, then something of the form:

const astr1[] = "Alpha";
...
const astrx[] = "Omega";
const bstr1[] = "Alef";
...
const bstrx[] = "Tav";
const char* A[] = {astr1,...,astr x};
const char* B[] = {bstr1,...,bstr x};
const char **a = A;
...
a = B;
and anywhere in your code you can say
strings = a;
Sep 10 '08 #6
"Andrea Taverna (Tavs)" <a.****@libero. itwrites:
Ok, I've tried both ways, Barry's and Pete's. GCC still wars about
compatibility, but it behaves correctly at run time, so the problem is
set.
Don't be satisfied with code that produces warnings. Understand why
the warning is being produced. Most of the time, you should fix the
code so the warning goes away (note: adding a cast is rarely the right
fix). In some cases, it makes sense to leave the code as it is and
accept the warning, but most warnings indicate a real problem in the
code, one that's likely to bite you later on.

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Sep 10 '08 #7
On Wed, 10 Sep 2008 16:16:23 +0200, "Andrea Taverna (Tavs)"
<a.****@libero. itwrote:
>Barry Schwarz ha scritto:
>In this case, sizeof a will probably be 4 or 8.
>>I need it to be initialized as an array of strings, something like

static const char **a = {"Alpha", "Beta", Charlie"};

I know the number of strings and their maximum length, but I can't use a
stack-allocated matrix for compatibility reasons with another piece of
code, which simply defines a

char** strings
>> to which the matrix has to be assigned to.

There should be no problem "assigning the array" to this pointer.

Actually there is. GCC warns that they're not compatible
I would be nice if you told us what the warning said. It is probably
a complaint about loss of "const" so remove that qualifier from your
code.
>
>On the other hand, if you need a true pointer that can be reassigned
to point to different sets of strings, then something of the form:

const astr1[] = "Alpha";
...
const astrx[] = "Omega";
const bstr1[] = "Alef";
...
const bstrx[] = "Tav";
const char* A[] = {astr1,...,astr x};
const char* B[] = {bstr1,...,bstr x};
const char **a = A;
...
a = B;
and anywhere in your code you can say
strings = a;

that's precisely what I'm going to do.
You will still have the const problem.

--
Remove del for email
Sep 11 '08 #8
>I would be nice if you told us what the warning said. It is probably
>a complaint about loss of "const" so remove that qualifier from your
code.
Sure.
I don't have the code at hand. More or less it says:
"Warning: assignment between incompatible types"

We fixed it by adjusting the declaration of the 'strings' field.
Now they're both declared as const char**, and the problem would be solved.
However I had to change the C standard from gnu89 (gcc's default) to
c99, and with the following piece of code

const char * a [] =
{
"alpha", "beta","charlie "
};

const struct my_structure my_s = (const struct my_structure)
{
.x = 10;
.strings = a; // <- Error
};

and the latter standard it complains with the following message:
"Error: initializer element is not constant"
With gnu89 it compiles fine.
Sep 19 '08 #9
On Fri, 19 Sep 2008 19:43:53 +0200, "Andrea Taverna (Tavs)"
<a.****@libero. itwrote:
I would be nice if you told us what the warning said. It is probably
a complaint about loss of "const" so remove that qualifier from your
code.
Sure.
I don't have the code at hand. More or less it says:
"Warning: assignment between incompatible types"

We fixed it by adjusting the declaration of the 'strings' field.
Now they're both declared as const char**, and the problem would be solved.
However I had to change the C standard from gnu89 (gcc's default) to
c99, and with the following piece of code

const char * a [] =
{
"alpha", "beta","charlie "
};

const struct my_structure my_s = (const struct my_structure)
{
.x = 10;
.strings = a; // <- Error
};

and the latter standard it complains with the following message:
"Error: initializer element is not constant"
With gnu89 it compiles fine.
If this code is outside of a function then my_s has static duration.
Initialization of a static object must be a compile time constant
since it occurs before any code is executed. The same restriction
applies to compound literals outside of a function body (6.5.2.5-3).

I can't help with gnu89 except to suggest that you specify the
appropriate options to prohibit extensions.

--
Remove del for email
Sep 20 '08 #10

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

Similar topics

21
2017
by: JKop | last post by:
Is this them all?: class Dummy { public: Dummy() {} Dummy(const Dummy& original) { }
9
2730
by: Steven T. Hatton | last post by:
The following works: template <typename T> struct ID3M{ static const T ID; }; template <typename T> const T ID3M<T>::ID = {{1,0,0},{0,1,0},{0,0,1}};
2
1623
by: Matthias Kaeppler | last post by:
Hi, say I have an arbitrary class Bar: 1 Bar a; 2 Bar b(a); 3 Bar c = a; In line 3, is the default ctor called for c _first_ and _then_ the assignment operator, or is c never default constructed and immediately
4
4670
by: Javi | last post by:
Hello there!. I would like to create a class with an array as attribute. This array is the same for all the objects so I'd like to declare it as static, but the problem is: where and how should I define the elements of the array, in the constructor?. I've tried the following code but It doesn't work at all: class hamiltonian{
4
9687
by: Stephen Mayes | last post by:
I have initialized an array like this. const char matrix = { {0, 1, 2, 3}, {0, 1, 2}, {0, 1} }; gcc, (with no options set,) errors unless I specify
4
1577
by: Marcus Kwok | last post by:
I found a bug in VC++ .NET 2003 regarding default initialization of arrays of primitives in a constructor initialization list, as detailed in this post: http://groups.google.com/group/comp.lang.c++/msg/dab44a8b786b6a79 and in the reply by Dietmar Kuehl, in which he quotes the relevant portion of the C++ Standard: http://groups.google.com/group/comp.lang.c++/msg/71a9fecc4f5d7d57 I tried to file a bug report at
15
2102
by: luke.yolanda | last post by:
hi everyone I have a question. First, I have implemented a huge matrix in a program, like 'unsigned char matrix;', when I executed this program, the error occured. Then I modified the declaration, like 'static unsigned char matrix;', it runs well.
2
1611
by: WinniePooh | last post by:
Hi there, I've the following code (here a snippet). ///////////////////////////////// // *.h file ///////////////////////////////// class ParameterTypeNames { public: static const std::string FLOAT; static const std::string INT; // ...
23
3661
by: Jess | last post by:
Hello, I understand the default-initialization happens if we don't initialize an object explicitly. I think for an object of a class type, the value is determined by the constructor, and for the built-in types, the value is usually garbage. Is this right? However, I'm a bit confused about value-initialization, when does it happen, and what kind of values are assigned to objects?
2
1831
by: subramanian100in | last post by:
Consider the following program: #include <iostream> using namespace std; class Base { public: Base(int x = 0);
0
8776
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
1
9236
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9182
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
6735
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 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 a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6031
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4550
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4809
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3261
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2724
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

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.