Const Issue

A

arnuld

This program compiles with a warning and of course it is working and
running fine:


#include <stdio.h>
#include <stdlib.h>
#include <string.h>


enum {
VAL_FALSE = 0,
VAL_TRUE = 1
};


int array_has_two_newlines_together(const char* s);



int main(void)
{
char arr1[] = "This has 2 newlines together\n\n";
char arr2[] = "This has 2 newlines \n but not together\n";
char arr3[] = "This has only one newline\n";
char arr4[] = "This does not have any newlines";

if(VAL_TRUE == array_has_two_newlines_together(arr1))
{
printf("arr1 has 2 newlines together\n");
}

if(VAL_TRUE == array_has_two_newlines_together(arr2))
{
printf("arr2 has 2 newlines together\n");
}

if(VAL_TRUE == array_has_two_newlines_together(arr3))
{
printf("arr3 has 2 newlines together\n");
}

if(VAL_TRUE == array_has_two_newlines_together(arr4))
{
printf("arr4 has 2 newlines together\n");
}


return 0;
}



int array_has_two_newlines_together(const char* s)
{
char* p = s;

for(; *p; ++p)
{
if( ('\n' == *p) && ('\n' == *(p+1)) )
{
return VAL_TRUE;
}
}

return VAL_FALSE;
}

=================== OUTPUT ============================
[arnuld@dune programs]$ gcc -ansi -pedantic -Wall -Wextra two-
newlines.c
two-newlines.c: In function ‘array_has_two_newlines_together’:
two-newlines.c:51: warning: initialization discards qualifiers from
pointer target type

[arnuld@dune programs]$ ./a.out
arr1 has 2 newlines together




I understand the warning easily. Line 51 is:

char* p = s; (in array_has_two_newlines_together())


I am trying to initialize a non-const pointer from a const one. In
what way I should write my function to stop this warning. The array
has to be const because I am not thinking of modifying it at all. Just
reading/browsing through it comparing elements. I changed the argument
declaration from:

const char* --> char *const

and now it compiles without warning but is it the correct thing to
do ?
 
C

Charles Keepax

  const char*  --> char *const

and now it compiles without warning but is it the correct thing to
do ?

const char* pTest = &thing;
- Means that the char that is pointed to is a constant
- So pTest[0] = 1; is illegal
- And pTest = &otherthing; is legal

char* const pTest = &thing;
- Means that the point is constant but the data can be changed
- So pTest[0] = 1; is legal
- But pTest = &otherthing; is illegal

All you need to do is change line 51 to:
const char* p = s;

Although is there any reason to not just do away with p all together
and just use s in your for loop.

Hope that helps,
Charles Keepax
 
B

Ben Bacarisse

arnuld said:
This program compiles with a warning and of course it is working and
running fine:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

enum {
VAL_FALSE = 0,
VAL_TRUE = 1
};

If you can assume C99, use its bool type from stdbool.h.
int array_has_two_newlines_together(const char* s);

int main(void)
{
char arr1[] = "This has 2 newlines together\n\n";
char arr2[] = "This has 2 newlines \n but not together\n";
char arr3[] = "This has only one newline\n";
char arr4[] = "This does not have any newlines";

if(VAL_TRUE == array_has_two_newlines_together(arr1))

Yuck! You've picked a lovely name for the function so there is no need
to ask if what it returns is equal to true, just ask if it is true:

if (array_has_two_newlines_together(arr1)) ...

The == operator produces 0 or 1 as does you function. if you feel the
need to test if your function returns VAL_TRUE, you get into an infinite
regress. Why not test that VAL_TRUE == (VAL_TRUE == f(x)), and so on?

int array_has_two_newlines_together(const char* s)
{
char* p = s;

for(; *p; ++p)
{
if( ('\n' == *p) && ('\n' == *(p+1)) )

I'd write p[1] rather than *(p+1) and then I'd probably use p[0] also
just to keep it looking symmetric. Personally, I don't bracket
relational tests inside && and ||. Is there going to any doubt in the
mind of any reader of your code that '\n' == p[0] && '\n' == p[1] does
what it should?
{
return VAL_TRUE;
}
}

return VAL_FALSE;
}

It is a good idea to learn the C library:

return strstr(s, "\n\n") != NULL

does the job for you in one line.
=================== OUTPUT ============================
[arnuld@dune programs]$ gcc -ansi -pedantic -Wall -Wextra two-
newlines.c
two-newlines.c: In function ‘array_has_two_newlines_together’:
two-newlines.c:51: warning: initialization discards qualifiers from
pointer target type

I am trying to initialize a non-const pointer from a const one.

Technically, neither pointer is const -- they point to const and
non-const data. Most people use this shorthand, though, but it can
cause a lot of confusion when the distinction matters (e.g. when two
levels of pointers are involved).
In
what way I should write my function to stop this warning. The array
has to be const because I am not thinking of modifying it at all. Just
reading/browsing through it comparing elements. I changed the argument
declaration from:

const char* --> char *const

and now it compiles without warning but is it the correct thing to
do ?

No. Much better to change p to match s:

const char *p = s;

Then again, I would not use another pointer. s can be moved along the
string just as well as p can be.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top