473,802 Members | 2,294 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Setting a const char * in an **argv

86 New Member
On my platform, I see that if I do following:

Expand|Select|Wrap|Line Numbers
  1. void myFunc( const char *myArg )
  2. {
  3.     char **argv;
  4.  
  5.     argv = &myArg;
  6.  
  7.     createTask( ....., argv, .... );
  8.  
  9. }
Compiler complains that I cannot assing argv to point to &myArg - only if the parameter is defined as 'const'. Without the 'const', it works fine.

I wonder then why the address of "myArg" poses trouble to cast it to char ** if it's a const. Does anybody have a clue?
Aug 6 '08 #1
9 3621
Banfa
9,065 Recognized Expert Moderator Expert
const char * is a pointer to constant char (or and array of constant char)

char ** is a pointer to pointer to char

The assignment/cast you have done looses the constness of the data you are pointing to and is therefore illegal for a implicit cast.

Without the const you are not loosing the constness of the data and therefore there is no problem.

The other option is to add a const to you declaration of argv.


You could explicitly cast from const char * to char **, the compiler will do this but it is very bad practice as it removes any type safety that the compiler imposes.

In the worst case someone calling the function might pass data that is actually const, that is unchangeable in hardware, and because argv is not const the code using argv could try to change the data pointed to this would likely result in a hardware exception or fail operation of the program.
Aug 6 '08 #2
jorba101
86 New Member
You could explicitly cast from const char * to char **,
I'm not trying this, but trying a cast from ptr to const char * to char**. I guess it is what you meant.

I understand from your post that "const char *" means "char pointer to const data" (instead of const pointer to char data, which is what I thought this morning). How could I declare a const char pointer to const char data? And a const pointer to const pointer to const char data? (yes, hard to read). Since I'm pointing "myArg" to a string given by a compile-time macro, I guess that would suit better my case (am I right?).

On the other hand, I can't change the parameters "createTask " is accepting, since it is from an API provided in binary shape (and deals with 99% of the other part of my environment, which is already provided too). Actually, I wonder why they did not made it "const" to "const", or more in general why "argv" as main parameter isn't either: It looks like a dirty hack changing main parameters inside main itself.

Thanks.-
Aug 6 '08 #3
edwardrsmith
62 New Member
If you are trying to point to a compile time macro it would be better to use true macro's by using the #define pre-compiler tag. Look up #define in google and that will show you how to use the tag. When it comes time to compile you will have to find out how your compiler allows you to assign macros at compile time.

Edward
Aug 7 '08 #4
jorba101
86 New Member
Oops,

maybe I should have said a #define instead of the more confusing term "compile-time macro". A #define is what I meant by "compile-time macro", and is what I'm actually using.
Aug 8 '08 #5
Banfa
9,065 Recognized Expert Moderator Expert
On the other hand, I can't change the parameters "createTask " is accepting, since it is from an API provided in binary shape (and deals with 99% of the other part of my environment, which is already provided too). Actually, I wonder why they did not made it "const" to "const", or more in general why "argv" as main parameter isn't either: It looks like a dirty hack changing main parameters inside main itself.
The reason the argv of main is not const is that it is derviced from the command line of the program. That means the system has to parse the command line and create the array passed as argv from it in memory.

Therefore the system is writing to memory and passing a pointer to that memory to main. By definition then this memory is not const.

I agree changing argv parameters seems like a dirty hack.


Another explanation is that I believe the const keyword did not exist in early versions of C but that future version have maintained backwards compatibility and therefore argv in main has remained without the const keyword.
Aug 8 '08 #6
donbock
2,426 Recognized Expert Top Contributor
On my platform, I see that if I do following:

Expand|Select|Wrap|Line Numbers
  1. void myFunc( const char *myArg )
  2. {
  3.     char **argv;
  4.     argv = &myArg;
  5.     createTask( ....., argv, .... );
  6. }
Compiler complains that I cannot assing argv to point to &myArg - only if the parameter is defined as 'const'. Without the 'const', it works fine.

I wonder then why the address of "myArg" poses trouble to cast it to char ** if it's a const. Does anybody have a clue?
myArg is a pointer to read-only chars. This means that myFunc promises not to change the chars pointed to by myArg.

The prototype for createTask apparently declares argv to be a pointer to a pointer to read/writeable chars. This means that the task being created has permission to overwrite the arguments -- which would violate the promise made by the function prototype for myFunc.

You could cast away the const-ness of myArg, but your program might halt and dump core if the created task goes ahead and tries to overwrite the arguments ... or it might work just fine. It depends on your compiler and precisely how myFunc is called.

I can think of two portable and bullet-proof ways to resolve this.

1. Change the prototype for myFunc to declare myArg as "char *". That is, take away the const-ness of myArg at the source rather than casting it away later. This may create new compiler warnings where myFunc is called. You can resolve those warnings by making analogous changes there.

2. Change myFunc to allocate a block of memory of equal size to that pointed to by myArg. (This could be either a dynamic or static allocation depending on exactly how your program sets the size of that block.) Then copy the block pointed to by myArg into your local block. Finally pass a non-const pointer to that local block to createTask. The created task is then free to overwrite the local copy of the arguments. This is only possible if myFunc knows or can compute the size of the block pointed to by myArg.

In the worst case someone calling the function might pass data that is actually const, that is unchangeable in hardware, and because argv is not const the code using argv could try to change the data pointed to this would likely result in a hardware exception or fail operation of the program.
Write-protected hardware is certainly a good reason to use const, but it isn't the only one; although you're right in that it is the most likely way for casting away const-ness to result in a problem for this program.

One minor comment: the name "argv" is not reserved, but its typical usage is as one of the arguments to main(). That isn't exactly the way you're using it here. You might reduce confusion by renaming this variable to something like taskArgv.

Cheers,
Don
Aug 9 '08 #7
donbock
2,426 Recognized Expert Top Contributor
I understand from your post that "const char *" means "char pointer to const data" (instead of const pointer to char data, which is what I thought this morning). How could I declare a const char pointer to const char data? And a const pointer to const pointer to const char data? (yes, hard to read).
The short answer is that it depends on whether the word const appears before or after the asterisk (*). This answer is so short that it doesn't really help you.

A slightly longer answer is that you should read pointer declarations involving const and volatile from right to left:
Expand|Select|Wrap|Line Numbers
  1. int * const ptr = &someInt;
  2. volatile int * const * whatIsThis;
ptr is a const pointer to an int. You can change *ptr; but you can't change ptr.

whatIsThis is a pointer to a const pointer to a volatile int. You can change whatIsThis; you can change **whatIsThis; but can't change *whatIsThis.

For a really good answer you should use google to find one of the many well-written essays on this topic that are on internet.

Cheers,
Don
Aug 9 '08 #8
donbock
2,426 Recognized Expert Top Contributor
2. Change myFunc to allocate a block of memory of equal size to that pointed to by myArg. (This could be either a dynamic or static allocation depending on exactly how your program sets the size of that block.) Then copy the block pointed to by myArg into your local block. Finally pass a non-const pointer to that local block to createTask. The created task is then free to overwrite the local copy of the arguments. This is only possible if myFunc knows or can compute the size of the block pointed to by myArg.
Sorry, that is possibly a very bad idea. Does the task being created persist after myFunc returns? If so, then the quoted suggestion could easily lead to the argv argument to the created task pointing to freed memory. The result would be disastrous. The quoted suggestion could still be used if you were careful to do it in such a way that the local memory block persisted beyond the end of myFunc. But then you might have to worry about a memory leak.
Cheers,
Don
Aug 9 '08 #9
jorba101
86 New Member
Well,

First thanks a lot for your suggestions and explanations.

The reason for using const char * was that I was pointing it to a compile-time string (with #define). Compiler did not allow me to do the assignation if I did it to a char *.

So. I looked twice the function the API provides to create a task, which accepts an argv and an argc (this one being int). Instead of passing a string, I passed a number through argc, which suited better my application. At first I did not like this solution since it is a bit of hacking the meaning we know argc and argv should have. Anyaway, I contacted support for the API and told me that there is no process done by my OS with argc and argv, so their values should not keep any relationship.

Your second solution was fine to my case, since after creating the task I wait for it to finnish (it sends a packet, awaits ACK, and joins the thread of myFunc).
Aug 11 '08 #10

Sign in to post your reply or Sign up for a free account.

Similar topics

3
2240
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. Someone on the SuSE programming mailing list suggested my problem is that I'm trying to execute a function (I assume he meant the constructor) at compile time. The same source code compile if I don't try to split it up into separate libraries. ...
10
8727
by: JKop | last post by:
Why isn't: int main(int argc, char* argv) { /* ... */ } as: int main(int argc, const char* argv)
5
22071
by: Brad Moore | last post by:
Hey all, I'm getting the following compiler error from my code. I was wondering if anyone could help me understand the concept behind it (I actually did try and compile this degenerate example). int foo(const char* argv) { return 0; } int main(int argc, char* argv) {
16
41779
by: herbertF | last post by:
Hi guys, In a program (not my own) I encountered the declaration of a constant pointer to an array consisting of two other const pointers to arrays. Not quite sure why they do it so complicated, but is it legal? Most compilers accept it, but one doesn't recognize the rhs as a constant. What are the requirements for the rhs in the declaration of a const pointer? Is the following program legal C? int main(int argc, char *argv) {
5
1831
by: sugaray | last post by:
I wrote a short code as shown below for experiment purpose, It is successfully compilable, yet I found the piece I wrote even confused myself with the consts and the asterisks, and which brought up three questions to me: 1) will the casting in line 1 affect the rest of the declarations ? 2) what's the difference between line 2 and line 3 3) are there any practical purposes of the usage of any of the three ?
10
3286
by: kevin.hall | last post by:
GCC 3.3 and MSVS 6.0 have no problem converting char* to const char* (not even a warning), but MS's WinCE compiler generated an error complained that this was not possible. MS's WinCE compiler did allow a conversion from char* to const char** though. I'm interested in what the standard would say about this. (I don't have a copy.) Many thanks,
7
8562
by: Eric | last post by:
Hi For this code, int getopt (int argc, char *const argv, const char *opts) what does the "char *const argv" mean? Does it equal to "char **const argv"? Or "char *const *argv"? Which is the const? Thanks
7
3518
by: Martin | last post by:
When referring to the conforming declaration for main, Lint displays Info 818: Pointer parameter 'argv' (line 3) could be declared as pointing to const Presumably it's saying that the definition could be: int main(int argc, char *const *argv) Why didn't C89 mandate that?
35
34600
by: Sean Farrow | last post by:
Hi: What is best and safest way of converting a char* to a const char *? Can I use const_cast? Cheers Sean.
0
9699
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9559
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,...
0
10529
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10301
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10280
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,...
1
7596
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
6835
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
5620
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4268
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

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.