LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 12-20-2004, 01:59 PM   #1
hubabuba
Member
 
Registered: Jan 2002
Location: UK
Distribution: Slack 14.1
Posts: 193

Rep: Reputation: 30
warning: comparison is always false due to limited range of data type


Hi

I get the following warning message for the program:

warning: comparison is always false due to limited range of data type

Code for my program:

Code:
#include <stdio.h>
#include <string.h>

char stringLessThan(const char string1[], const char string2[]);

int main(void)
{
  char string1[BUFSIZ], string2[BUFSIZ];

  printf("First string: ");
  gets(string1);
  printf("Second String: ");
  gets(string2);
  
  if (stringLessThan(string1, string2) == 'TRUE')
    printf("TRUE\n");
  else
    printf("FALSE\n");
}  

char stringLessThan(const char string1[], const char string2[])
{
  if (strcmp(string1, string2) < 0)
    return 'TRUE';
  else 
    return 'FALSE';
}
 
Old 12-20-2004, 02:06 PM   #2
deiussum
Member
 
Registered: Aug 2003
Location: Santa Clara, CA
Distribution: Slackware
Posts: 895

Rep: Reputation: 31
You are trying to take the values of 'TRUE' and 'FALSE' and return a single char... the literals 'TRUE' and 'FALSE' actually represent a 4 byte integer, not a single char. You cannot store 4 bytes of data into a 1 byte char.

Try changing it to return a single char, or just return 0 or 1...

Edit: Actually there would be 5 bytes in 'FALSE' so that actually even be too long for a 4 byte int... testing the simple program below with g++ I get the following:

Code:
#include <iostream>

using namespace std;

main()
{
    cout << sizeof('TRUE') << endl;
    cout << sizeof('FALSE') << endl;
}
Results:
Code:
$ g++ -o blah blah.cpp
blah.cpp:7:24: warning: multi-character character constant
blah.cpp:8:24: warning: character constant too long for its type

$ ./blah
4
4

Last edited by deiussum; 12-20-2004 at 02:11 PM.
 
Old 12-20-2004, 02:22 PM   #3
hubabuba
Member
 
Registered: Jan 2002
Location: UK
Distribution: Slack 14.1
Posts: 193

Original Poster
Rep: Reputation: 30
Thanks for your reply.

I've changed function's char type to int type and the program works althoug i still get messages:

warning: multi-character character constant
warning: character constant too long for its type
 
Old 12-20-2004, 02:43 PM   #4
Tinkster
Moderator
 
Registered: Apr 2002
Location: in a fallen world
Distribution: slackware by choice, others too :} ... android.
Posts: 22,966
Blog Entries: 11

Rep: Reputation: 865Reputation: 865Reputation: 865Reputation: 865Reputation: 865Reputation: 865Reputation: 865
That's because 'TRUE' is 4 chars, not one.
If you want to return a string of four you'll
have to make a few adjustments... ;0


Cheers,
Tink
 
Old 12-20-2004, 02:44 PM   #5
Hko
Senior Member
 
Registered: Aug 2002
Location: Groningen, The Netherlands
Distribution: ubuntu
Posts: 2,530

Rep: Reputation: 108Reputation: 108
Fixed your program
Note the /* comments */

Code:
#include <stdio.h>
#include <string.h>

/* You didn't define BUFSIZE at all ! */
#define BUFSIZE 256

/* Define macro's for bool values that expand to numbers */
#define FALSE 0   
#define TRUE  1

char stringLessThan(const char string1[], const char string2[]);

int main(void)
{
    char string1[BUFSIZ], string2[BUFSIZ];

    printf("First string: ");
    fgets(string1, BUFSIZE, stdin);
    printf("Second String: ");
    fgets(string2, BUFSIZE, stdin);

    if (stringLessThan(string1, string2) == TRUE) /* you can remove "== TRUE" if you like. */
        printf("TRUE\n");
    else
        printf("FALSE\n");
    return 0;  /* Report "succesful finished" back to the shell */
}

char stringLessThan(const char string1[], const char string2[])
{
    if (strcmp(string1, string2) < 0)
        return TRUE;   /* Note: removed single quotes */
    else
        return FALSE;
}
 
Old 12-20-2004, 03:08 PM   #6
deiussum
Member
 
Registered: Aug 2003
Location: Santa Clara, CA
Distribution: Slackware
Posts: 895

Rep: Reputation: 31
I think you got the first warning, because multicharacter character constants are seldom used in my experience, so the compiler was warning you in case you didn't really want to do that. The second warning was because FALSE is 5 bytes, so it couldn't be properly stored in a 4 byte int.

Note: 'TRUE' works out to the value 0x54525545, because the letters have the following ASCII values:

T = 0x54
R = 0x52
U = 0x55
E = 0x45

If you take a look at Hko's sample code, he shows you the more common way to create TRUE and FALSE constants...
 
Old 12-20-2004, 04:56 PM   #7
Dark_Helmet
Senior Member
 
Registered: Jan 2003
Posts: 2,786

Rep: Reputation: 369Reputation: 369Reputation: 369Reputation: 369
Not to beat a dead horse, but I wanted to say something that nobody else has addressed yet.

In C/C++ there is a difference between using single quotes ( ' ) and double quotes ( " ). Using single quotes implies a character literal. More specifically, a char variable. Using double quotes implies a string (multi-char sequence terminated by a NULL).

So, typing 'TRUE' or 'FALSE' doesn't make any sense, and I would have expected the compiler to complain... loudly (as in a fatal error). You could have used 'T' and 'F' however.

Last edited by Dark_Helmet; 12-20-2004 at 05:05 PM.
 
Old 12-20-2004, 04:57 PM   #8
Hivemind
Member
 
Registered: Sep 2004
Posts: 273

Rep: Reputation: 30
I would advise against using the preprocessor to create symbolic names for compile-time constants.
 
Old 12-21-2004, 07:10 AM   #9
bigearsbilly
Senior Member
 
Registered: Mar 2004
Location: england
Distribution: FreeBSD, Debian, Mint, Puppy
Posts: 3,284

Rep: Reputation: 172Reputation: 172
as Dark said,
'TRUE' is meaningless in C.
It's not a string, not a char.

it's not good practice to return a string from a function.
don't do it.

follow the C convention, return zero for false and non-zero for true.

regards billy
 
Old 12-21-2004, 08:09 AM   #10
hubabuba
Member
 
Registered: Jan 2002
Location: UK
Distribution: Slack 14.1
Posts: 193

Original Poster
Rep: Reputation: 30
Thanks, i appreciate your help. It is clear to me now
 
Old 12-21-2004, 08:41 AM   #11
deiussum
Member
 
Registered: Aug 2003
Location: Santa Clara, CA
Distribution: Slackware
Posts: 895

Rep: Reputation: 31
Actually, 'TRUE' in both C and C++ is prefectly valid. It just doesn't have quite the same meaning as a typical char literal. As I stated before, this is called a multicharacter character constant. It is seldom used, which is why the compiler probably issues a warning. (The fact that few people know about it is further evidence that it is very seldom used. I thought it must be wrong the first time I ever saw it too...)

As I stated before, when using a multicharacter character constant like that, it basically converts to a 4 byte integer. I put the actual values of what 'TRUE' evaluates to above, but if you want to test yourself, try the following:

Code:
#include <stdio.h>

main()
{
    printf("'TRUE' = 0x%x\n", 'TRUE');
}
Result:
Code:
$ gcc -o blah blah.c
blah.c:5:35: warning: multi-character character constant
$ ./blah
'TRUE' = 0x54525545
I could be wrong, but I believe that the idea of multicharacter character constants originated with the usage of wide character sets, which generally use 2 bytes per character...

Trying to search for some more info on them, but there doesn't even seem to be much on Google. If I find anything of interest I'll post it here.

Edit:
I didn't find much that was conclusive information on this, but apparently, the ANSI C specification states that the behavior of multicharacter constants is implementation specific. Here is a Usenet thread that quotes a few documents on the topic:


Edit 2:
Found another link that talks a bit about the GNU implementation of multi-character character constants here.

Here's a quote from part of it:
Quote:
The compiler values a multi-character character constant a character at a time, shifting the previous value left by the number of bits per target character, and then or-ing in the bit-pattern of the new character truncated to the width of a target character. The final bit-pattern is given type int, and is therefore signed, regardless of whether single characters are signed or not (a slight change from versions 3.1 and earlier of GCC). If there are more characters in the constant than would fit in the target int the compiler issues a warning, and the excess leading characters are ignored.

Last edited by deiussum; 12-21-2004 at 09:16 AM.
 
Old 12-21-2004, 08:46 AM   #12
bigearsbilly
Senior Member
 
Registered: Mar 2004
Location: england
Distribution: FreeBSD, Debian, Mint, Puppy
Posts: 3,284

Rep: Reputation: 172Reputation: 172
well, you learn something new everyday.

that could confuse a stupid person!

:-)
 
Old 12-21-2004, 09:42 AM   #13
deiussum
Member
 
Registered: Aug 2003
Location: Santa Clara, CA
Distribution: Slackware
Posts: 895

Rep: Reputation: 31
I know what you mean bigearsbilly. Just when you think you know everything about C/C++, you learn some new obscure thing like this. I'm not sure why, but obscure stuff like this interests me and usually sticks in my head...

BTW, I am probably wrong about the multicharacter constants originating for wide character sets. Literals for those are generally signified something like: wchar_t ch = L'a';. It sounds like the multicharacter constant like 'abcd' is specifically for providing a different way to give a literal integer value.

I think the first place I ever saw this convention used was in some sample code for writing apps for PalmOS using their modified gcc compiler... I was like, WTF!?!
 
Old 12-21-2004, 10:03 AM   #14
bigearsbilly
Senior Member
 
Registered: Mar 2004
Location: england
Distribution: FreeBSD, Debian, Mint, Puppy
Posts: 3,284

Rep: Reputation: 172Reputation: 172
true.
that's why i love Unix/Linux.

you can never know it all.

always something new. Even if you read a man page
on something like diff or uniq or even ls you'll find something you didn't
know and which was really useful.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
mysql - load data warning prabhatsoni Linux - Software 0 06-16-2005 06:08 AM
What is the warning: passing arg 3 of `pthread_create' from incompatible pointer type wallwaters Linux - Software 3 06-01-2005 08:30 AM
Outgoing data rate limited per connection: how to fix? chrismear Linux - Networking 2 12-24-2004 06:51 PM
Copy Paste of data from word to Yahoo/rediff in opera is limited to few characters sachin_keluskar Linux - Software 0 08-19-2004 09:46 AM
C programming error. warning: comparison between pointer and integer Linh Programming 4 06-06-2003 03:49 PM


All times are GMT -5. The time now is 12:52 AM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration