473,383 Members | 1,815 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,383 software developers and data experts.

Annoying const problem

I have a function that always takes 16 bytes of data and doesn't modify
it:

void func( byte const (*data)[16] );

However, if I try to call it with non-const data, the compiler is
unable to perform the conversion:

static const byte bar1[16] = { 0 };

int foo()
{
byte bar2[16] = { 0 };

func( &bar1 ); /* OK */
func( &bar2 ); /* Error */
}

Is there any work-around to this, other than defining a const and a
nonconst version of func, or passing a pointer to the first element
of data and thereby losing the compile-time length check?

Dec 10 '06 #1
13 1441
Old Wolf wrote:
>
I have a function that always takes 16 bytes of data and doesn't
modify it:

void func( byte const (*data)[16] );

However, if I try to call it with non-const data, the compiler is
unable to perform the conversion:

static const byte bar1[16] = { 0 };

int foo()
{
byte bar2[16] = { 0 };

func( &bar1 ); /* OK */
func( &bar2 ); /* Error */
}

Is there any work-around to this, other than defining a const and a
nonconst version of func, or passing a pointer to the first element
of data and thereby losing the compile-time length check?
Probably it will be enough to compile with a C compiler. Looks
like you are using C++.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>

Dec 10 '06 #2
In article <11**********************@n67g2000cwd.googlegroups .com>,
Old Wolf <ol*****@inspire.net.nzwrote:
>void func( byte const (*data)[16] );
[Presumably byte is typedefed.]
>However, if I try to call it with non-const data, the compiler is
unable to perform the conversion:
You'll have to put in an explicit cast:

func( (byte const (*)[16]) &bar2 );

Of course, this loses the type checking, but only for the cases where
you cast it.

-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
Dec 10 '06 #3
CBFalconer wrote:
Old Wolf wrote:
void func( byte const (*data)[16] );
static const byte bar1[16] = { 0 };

int foo()
{
byte bar2[16] = { 0 };

func( &bar1 ); /* OK */
func( &bar2 ); /* Error */
}

Probably it will be enough to compile with a C compiler. Looks
like you are using C++.
Actually I'm not. Thanks for guessing though. What C compiler are
you using that compiles this code without issuing a diagnostic?

typedef unsigned char byte;
void func( byte const (*data)[16] ) {}
int main()
{
byte bar[16] = { 0 };
func( &bar );
}

Dec 11 '06 #4
Old Wolf wrote:
I have a function that always takes 16 bytes of data and doesn't modify
it:

void func( byte const (*data)[16] );

However, if I try to call it with non-const data, the compiler is
unable to perform the conversion:

static const byte bar1[16] = { 0 };

int foo()
{
byte bar2[16] = { 0 };

func( &bar1 ); /* OK */
func( &bar2 ); /* Error */
}

Is there any work-around to this, other than defining a const and a
nonconst version of func, or passing a pointer to the first element
of data and thereby losing the compile-time length check?
I think not. The non-const version can, of course, be a wrapper for the
const version.

--
Thad
Dec 11 '06 #5
Old Wolf wrote:
CBFalconer wrote:
Old Wolf wrote:
void func( byte const (*data)[16] );
static const byte bar1[16] = { 0 };
>
int foo()
{
byte bar2[16] = { 0 };
>
func( &bar1 ); /* OK */
func( &bar2 ); /* Error */
}
Probably it will be enough to compile with a C compiler. Looks
like you are using C++.

Actually I'm not. Thanks for guessing though. What C compiler are
you using that compiles this code without issuing a diagnostic?

typedef unsigned char byte;
void func( byte const (*data)[16] ) {}
int main()
{
byte bar[16] = { 0 };
func( &bar );
}
The tendra compiler accepts it without a diagnostic. With extra
warnings enabled, it still only warns about an unused variable "data".
Of course, considering gcc, icc and comeau (online) all report an
error, I would not be surprised if it is a bug.

Dec 11 '06 #6
Old Wolf said:
I have a function that always takes 16 bytes of data and doesn't modify
it:

void func( byte const (*data)[16] );

However, if I try to call it with non-const data, the compiler is
unable to perform the conversion:

static const byte bar1[16] = { 0 };

int foo()
{
byte bar2[16] = { 0 };

func( &bar1 ); /* OK */
func( &bar2 ); /* Error */
}
Please produce the smallest *compilable* program (in the sense that it would
compile if not for your func(&bar2) call) that reproduces the problem.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Dec 11 '06 #7
Richard Heathfield wrote:
Old Wolf said:
I have a function that always takes 16 bytes of data and doesn't modify
it:
However, if I try to call it with non-const data, the compiler is
unable to perform the conversion:
Please produce the smallest *compilable* program (in the sense that it would
compile if not for your func(&bar2) call) that reproduces the problem.
See my response to CBF else-thread

Dec 11 '06 #8
Old Wolf said:

<snip>
typedef unsigned char byte;
void func( byte const (*data)[16] ) {}
int main()
{
byte bar[16] = { 0 };
func( &bar );
}
I hate questions like this, and I'm not going to try to explain it, but
FWIW:

typedef unsigned char byte;
void func( byte (* const data)[16] ) {} /* observe the difference here */
int main()
{
byte bar[16] = { 0 };
func( &bar );
return 0;
}

compiles cleanly (modulo one utterly irrelevant warning) under gcc, using
moderately strict flags (-W -Wall -ansi -pedantic).

So it seems to me that, once more, we are staring at C's recondite handling
of pointers to const data (as opposed to const pointers to data), the logic
of which I understood for about 20 minutes back in 2001, and promptly
forgot again.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Dec 11 '06 #9
In article <11*********************@n67g2000cwd.googlegroups. com>,
Old Wolf <ol*****@inspire.net.nzwrote:
>See my response to CBF else-thread
Since this thread has not yet included a (natural) language flame, I
would point out that "else-thread" should not mean what you want it to
mean. By analogy with "elsewhere", which means "somewhere else", it
should mean "somethread else" - that is, in a different thread.

-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
Dec 11 '06 #10
Richard Heathfield wrote:
Old Wolf said:
typedef unsigned char byte;
void func( byte const (*data)[16] ) {}
int main()
{
byte bar[16] = { 0 };
func( &bar );
}

I hate questions like this, and I'm not going to try to explain it, but
FWIW:

typedef unsigned char byte;
void func( byte (* const data)[16] ) {} /* observe the difference here */
int main()
{
byte bar[16] = { 0 };
func( &bar );
return 0;
}

compiles cleanly (modulo one utterly irrelevant warning) under gcc, using
moderately strict flags (-W -Wall -ansi -pedantic).
This is a top-level const, which is only relevant within func,
it does not affect what you can pass to it. So this version does
not allow:

byte const baz[16] = { 0 };
func(&baz);

which was part of my original problem and I should have included
it in the above sample code.
So it seems to me that, once more, we are staring at C's
recondite handling of pointers to const data (as opposed
to const pointers to data), the logic of which I understood
for about 20 minutes back in 2001, and promptly forgot again.
The above code seems to demonstrate that an array of objects,
each of which is const, is somehow different to a const array of
objects, each of which is not const.

If you understood this, then you understood it for 20 minutes
more than I did :)

FWIW the code compiles successfully in C++.

Dec 11 '06 #11
In article <11**********************@80g2000cwy.googlegroups. com>
Old Wolf <ol*****@inspire.net.nzwrote:
["const" problem illustrations snipped]
>FWIW the code compiles successfully in C++.
Sadly, the "const" rules in C are just broken. (The C++ rules
work. They do, however, pretty much need a lot of the rest of the
C++ machinery -- such as function overloading -- to work consistently.
C could have used the C++ rules, but the result would still be less
secure than the C++ rules, due to functions like strchr() removing
"const" qualifiers [in C].)

My preferred solution is to omit "const" as much as possible in C
code, but I recognize that not everyone favors this approach. :-)

I also wish that, in lieu of the C folks using "correct" rules
a la C++, they had simply made "const" a storage modifier rather
than a "type qualifier". In this case, "const" would have meant
"put this object into read-only memory if possible", but would have
had no effect at all on its type. Many argue that this would lose
some type-safety, but given, e.g.:

const char *qual;
...
char *unqual = strchr(unqual, *unqual);

we already get C code that quietly removes "const", so I think this
"some" type-safety is "very little" type-safety, and not worth its
cost.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Dec 12 '06 #12
In article <el*********@news1.newsguy.comI wrote, in part:
const char *qual;
...
char *unqual = strchr(unqual, *unqual);
Gah. This call is, of course, supposed to read:

char *unqual = strchr(qual, *qual);
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Dec 12 '06 #13
On Tue, 12 Dec 2006 06:53:45 +0000, Chris Torek wrote:
In article <el*********@news1.newsguy.comI wrote, in part:
> const char *qual;
...
char *unqual = strchr(unqual, *unqual);

Gah. This call is, of course, supposed to read:

char *unqual = strchr(qual, *qual);
strchr()/strrchr() is a big wart (but then so is all of string.h, IMO).

However it is possible/easy/better to have a string API that doesn't
return a pointer to offsets within itself (and if you insist on
using string.h then strspn/strcspn can easily be used).
And non-string APIs tend to not even consider design decisions like that.
So, while const does have it's problems (see earlier in this thread),
using a (const Foo *foo) parameter in a function provides great
documentation and is worth using.

--
James Antill -- ja***@and.org
http://www.and.org/and-httpd/ -- $2,000 security guarantee
http://www.and.org/vstr/
Dec 12 '06 #14

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

Similar topics

10
by: Douglas Buchanan | last post by:
I am using the following code instead of a very lengthly select case statement. (I have a lot of lookup tables in a settings form that are selected from a ListBox. The data adapters are given a...
3
by: Chris Mantoulidis | last post by:
I posted this here one day ago but it seems like it hasn't been put up for some unknown reason. That gives me a chance to say things a bit better in this post. 1st of all let's desribe the...
3
by: Steven T. Hatton | last post by:
Sorry about the big code dump. I tried to get it down to the minimum required to demonstrate the problem. Although this is all done with GNU, I believe the problem I'm having may be more general. ...
9
by: Alex | last post by:
Hi. I'll try my problem with this example: class C { protected: virtual int* getProtected(int index)=0; public: const int* get(int index) const { return (const int*) getProtected(index); } ...
5
by: Bit byte | last post by:
I have the following methods: static void Foo::setBar(const Bar*) ; //store a copy of Bar static const Bar* Foo::getBar(void) const ; //return an UNMODIFIABLE ptr to our internal copy In...
4
by: grizggg | last post by:
I have searched and not found an answer to this question. I ran upon the following statement in a *.cpp file in a member function: static const char * const pacz_HTMLContentTypeHeader =...
6
by: per9000 | last post by:
An interesting/annoying problem. I created a small example to provoke an exception I keep getting. Basically I have a C-struct (Container) with a function-pointer in it. I perform repeated calls...
2
by: nassim.bouayad.agha | last post by:
Hello, here is a code snippet showning my problem : template<typename _K> class TClass1 { public: void Process(const _K& arg) const {
12
by: hweekuan | last post by:
hi, it seems i can't assign the const variable u in class A, one way to solve the problem may be to build a copy constructor. however, why does C++ or vector class not like this code? my g++ is:...
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
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: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
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: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
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?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...

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.