How exactly is this function an example of a char to int conversion?












7















The book The C Programming Language by Kernighan and Ritchie, second edition states on page 43 in the chapter about Type Conversions:




Another example of char to int conversion is the function lower, which maps a single character to lower case for the ASCII character set. If the character is not an upper case letter, lower returns returns it unchanged.



/* lower: convert c to lower case; ASCII only */
int lower(int c)
{
if (c >= 'A' && c <= 'Z')
return c + 'a' - 'A';
else
return c;
}



It isn't mentioned explicitly in the text so I'd like to make sure I understand it correctly: The conversion happens when you call the lower function with a variable of type char, doesn't it? Especially, the expression



c >= 'A'


has nothing to do with a conversion from int to char since a character constant like 'A'
is handled as an int internally from the start, isn't it? Edit: Or is this different (e.g. a character constant being treated as a char) for ANSI C, which the book covers?










share|improve this question

























  • No, the conversion they are talking about happens inside the functuon body.

    – n.m.
    Dec 26 '18 at 7:48
















7















The book The C Programming Language by Kernighan and Ritchie, second edition states on page 43 in the chapter about Type Conversions:




Another example of char to int conversion is the function lower, which maps a single character to lower case for the ASCII character set. If the character is not an upper case letter, lower returns returns it unchanged.



/* lower: convert c to lower case; ASCII only */
int lower(int c)
{
if (c >= 'A' && c <= 'Z')
return c + 'a' - 'A';
else
return c;
}



It isn't mentioned explicitly in the text so I'd like to make sure I understand it correctly: The conversion happens when you call the lower function with a variable of type char, doesn't it? Especially, the expression



c >= 'A'


has nothing to do with a conversion from int to char since a character constant like 'A'
is handled as an int internally from the start, isn't it? Edit: Or is this different (e.g. a character constant being treated as a char) for ANSI C, which the book covers?










share|improve this question

























  • No, the conversion they are talking about happens inside the functuon body.

    – n.m.
    Dec 26 '18 at 7:48














7












7








7


1






The book The C Programming Language by Kernighan and Ritchie, second edition states on page 43 in the chapter about Type Conversions:




Another example of char to int conversion is the function lower, which maps a single character to lower case for the ASCII character set. If the character is not an upper case letter, lower returns returns it unchanged.



/* lower: convert c to lower case; ASCII only */
int lower(int c)
{
if (c >= 'A' && c <= 'Z')
return c + 'a' - 'A';
else
return c;
}



It isn't mentioned explicitly in the text so I'd like to make sure I understand it correctly: The conversion happens when you call the lower function with a variable of type char, doesn't it? Especially, the expression



c >= 'A'


has nothing to do with a conversion from int to char since a character constant like 'A'
is handled as an int internally from the start, isn't it? Edit: Or is this different (e.g. a character constant being treated as a char) for ANSI C, which the book covers?










share|improve this question
















The book The C Programming Language by Kernighan and Ritchie, second edition states on page 43 in the chapter about Type Conversions:




Another example of char to int conversion is the function lower, which maps a single character to lower case for the ASCII character set. If the character is not an upper case letter, lower returns returns it unchanged.



/* lower: convert c to lower case; ASCII only */
int lower(int c)
{
if (c >= 'A' && c <= 'Z')
return c + 'a' - 'A';
else
return c;
}



It isn't mentioned explicitly in the text so I'd like to make sure I understand it correctly: The conversion happens when you call the lower function with a variable of type char, doesn't it? Especially, the expression



c >= 'A'


has nothing to do with a conversion from int to char since a character constant like 'A'
is handled as an int internally from the start, isn't it? Edit: Or is this different (e.g. a character constant being treated as a char) for ANSI C, which the book covers?







c type-conversion kernighan-and-ritchie






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Dec 26 '18 at 0:55







efie

















asked Dec 25 '18 at 23:28









efieefie

376217




376217













  • No, the conversion they are talking about happens inside the functuon body.

    – n.m.
    Dec 26 '18 at 7:48



















  • No, the conversion they are talking about happens inside the functuon body.

    – n.m.
    Dec 26 '18 at 7:48

















No, the conversion they are talking about happens inside the functuon body.

– n.m.
Dec 26 '18 at 7:48





No, the conversion they are talking about happens inside the functuon body.

– n.m.
Dec 26 '18 at 7:48












3 Answers
3






active

oldest

votes


















4














Character constants have type int, as you expected, so you are correct that there are no promotions to int in this function.



Any promotion that may occur would happen if a variable of type char is passed to this function, and this is most likely what the text is referring to.



The type of character constants is int in both the current C17 standard (section 6.4.4.4p10):




An integer character constant has type
int




And in the C89 / ANSI C standard (section 3.1.3.4 under Semantics):




An integer character constant has type int




The latter of which is what K&R Second Edition refers to.






share|improve this answer





















  • 1





    K&R precedes the C standard. Is there reason to believe that, in their text, the type of 'a' was int and not char?

    – Eric Postpischil
    Dec 25 '18 at 23:46






  • 1





    @EricPostpischil On page 37 the book says: "A character constant is an integer, written as one character within single quotes, such as 'x'". I'm not sure if "is an integer" means "is of type int"?

    – efie
    Dec 25 '18 at 23:53








  • 2





    @efie: char, short, int, and long are all integer types, and an integer is just a value, so I do not think their reference to a character as an integer is informative.

    – Eric Postpischil
    Dec 25 '18 at 23:54











  • That makes sense, thanks. Regarding your first comment: On page two the book says: "The second edition of The C Programming Language describes C as defined by the ANSI standard."

    – efie
    Dec 26 '18 at 0:02



















4














K&R C is old. Really old. Many particulars of K&R C are no longer true in up-to-date standard C.



In stadard, up-to-date C11, there is no conversion to/from char in the function you posted:



/* lower: convert c to lower case; ASCII only */
int lower(int c)
{
if (c >= 'A' && c <= 'Z')
return c + 'a' - 'A';
else
return c;
}


The function accepts int arguments as int c, and per 6.4.4.4 Character constants of the C standard, character literals are of type int.



Thus the entire lower function, as posted, under C11 deals entirely with int values.



The conversion, if any, is may be done when the function is called:



char upperA = 'A`;

// this will implicitly promote the upperA char
// value to an int value
char lowerA = lower( upperA );


Note that this is one of the differences between C and C++. In C++, character literals are of type char, not int.






share|improve this answer
























  • Thanks! Do you know if a character constant was of type int in ANSI C as well? Or was it of type char which would add another explanation?

    – efie
    Dec 26 '18 at 0:43











  • Nothing whatsoever has changed about this function since C89.

    – n.m.
    Dec 26 '18 at 7:45



















2















How exactly is this function an example of a char to int conversion?




/* lower: convert c to lower case; ASCII only */
int lower(int c) {
if (c >= 'A' && c <= 'Z')
return c + 'a' - 'A';
else
return c;
}


It is not an example of a char to int conversion - technically incorrect by the author.





The text goes on to discuss tolower(c) as an alternative to lower() as it "works" correctly even if [A -Z] are not consecutively encoded as in EBCDIC.



What is not discussed, is that tolower() functions and others (is...()) are only specified for int values in the unsigned char range and EOF. C11 §7.4 1. Other values invoke undefined behavior (UB).



It is this requirement that makes these Standard C library functions conceptually char to int conversions as only values in the (about) char range are specified and the result is int.





Now look at code where char conversion does occur.



void my_strtolower1(char *s) {
while (*s) {
*s = lower(*s); // conversion `char` to `int` and `int` to `char`.
s++;
}
}

void my_strtolower2(char *s) {
while (*s) {
*s = tolower(*s); // conversion `char` to `int` and `int` to `char`.
s++;
}
}

void my_strtolower3(char *s) {
while (*s) {
// conversion `char` to `unsigned char` to `int` and `int` to `char`.
*s = tolower((unsigned char) *s);
s++;
}
}


my_strtolower1() well defined, yet not functionally correct on rare machines where [A-Z,a-z] are not consecutive.



my_strtolower2() expected functionality except technically undefined behavior when *s < 0 (and not EOF).



my_strtolower3() expected functionality without UB when *s < 0.






share|improve this answer

























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53926270%2fhow-exactly-is-this-function-an-example-of-a-char-to-int-conversion%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    4














    Character constants have type int, as you expected, so you are correct that there are no promotions to int in this function.



    Any promotion that may occur would happen if a variable of type char is passed to this function, and this is most likely what the text is referring to.



    The type of character constants is int in both the current C17 standard (section 6.4.4.4p10):




    An integer character constant has type
    int




    And in the C89 / ANSI C standard (section 3.1.3.4 under Semantics):




    An integer character constant has type int




    The latter of which is what K&R Second Edition refers to.






    share|improve this answer





















    • 1





      K&R precedes the C standard. Is there reason to believe that, in their text, the type of 'a' was int and not char?

      – Eric Postpischil
      Dec 25 '18 at 23:46






    • 1





      @EricPostpischil On page 37 the book says: "A character constant is an integer, written as one character within single quotes, such as 'x'". I'm not sure if "is an integer" means "is of type int"?

      – efie
      Dec 25 '18 at 23:53








    • 2





      @efie: char, short, int, and long are all integer types, and an integer is just a value, so I do not think their reference to a character as an integer is informative.

      – Eric Postpischil
      Dec 25 '18 at 23:54











    • That makes sense, thanks. Regarding your first comment: On page two the book says: "The second edition of The C Programming Language describes C as defined by the ANSI standard."

      – efie
      Dec 26 '18 at 0:02
















    4














    Character constants have type int, as you expected, so you are correct that there are no promotions to int in this function.



    Any promotion that may occur would happen if a variable of type char is passed to this function, and this is most likely what the text is referring to.



    The type of character constants is int in both the current C17 standard (section 6.4.4.4p10):




    An integer character constant has type
    int




    And in the C89 / ANSI C standard (section 3.1.3.4 under Semantics):




    An integer character constant has type int




    The latter of which is what K&R Second Edition refers to.






    share|improve this answer





















    • 1





      K&R precedes the C standard. Is there reason to believe that, in their text, the type of 'a' was int and not char?

      – Eric Postpischil
      Dec 25 '18 at 23:46






    • 1





      @EricPostpischil On page 37 the book says: "A character constant is an integer, written as one character within single quotes, such as 'x'". I'm not sure if "is an integer" means "is of type int"?

      – efie
      Dec 25 '18 at 23:53








    • 2





      @efie: char, short, int, and long are all integer types, and an integer is just a value, so I do not think their reference to a character as an integer is informative.

      – Eric Postpischil
      Dec 25 '18 at 23:54











    • That makes sense, thanks. Regarding your first comment: On page two the book says: "The second edition of The C Programming Language describes C as defined by the ANSI standard."

      – efie
      Dec 26 '18 at 0:02














    4












    4








    4







    Character constants have type int, as you expected, so you are correct that there are no promotions to int in this function.



    Any promotion that may occur would happen if a variable of type char is passed to this function, and this is most likely what the text is referring to.



    The type of character constants is int in both the current C17 standard (section 6.4.4.4p10):




    An integer character constant has type
    int




    And in the C89 / ANSI C standard (section 3.1.3.4 under Semantics):




    An integer character constant has type int




    The latter of which is what K&R Second Edition refers to.






    share|improve this answer















    Character constants have type int, as you expected, so you are correct that there are no promotions to int in this function.



    Any promotion that may occur would happen if a variable of type char is passed to this function, and this is most likely what the text is referring to.



    The type of character constants is int in both the current C17 standard (section 6.4.4.4p10):




    An integer character constant has type
    int




    And in the C89 / ANSI C standard (section 3.1.3.4 under Semantics):




    An integer character constant has type int




    The latter of which is what K&R Second Edition refers to.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Dec 26 '18 at 20:44

























    answered Dec 25 '18 at 23:43









    dbushdbush

    94.7k12101136




    94.7k12101136








    • 1





      K&R precedes the C standard. Is there reason to believe that, in their text, the type of 'a' was int and not char?

      – Eric Postpischil
      Dec 25 '18 at 23:46






    • 1





      @EricPostpischil On page 37 the book says: "A character constant is an integer, written as one character within single quotes, such as 'x'". I'm not sure if "is an integer" means "is of type int"?

      – efie
      Dec 25 '18 at 23:53








    • 2





      @efie: char, short, int, and long are all integer types, and an integer is just a value, so I do not think their reference to a character as an integer is informative.

      – Eric Postpischil
      Dec 25 '18 at 23:54











    • That makes sense, thanks. Regarding your first comment: On page two the book says: "The second edition of The C Programming Language describes C as defined by the ANSI standard."

      – efie
      Dec 26 '18 at 0:02














    • 1





      K&R precedes the C standard. Is there reason to believe that, in their text, the type of 'a' was int and not char?

      – Eric Postpischil
      Dec 25 '18 at 23:46






    • 1





      @EricPostpischil On page 37 the book says: "A character constant is an integer, written as one character within single quotes, such as 'x'". I'm not sure if "is an integer" means "is of type int"?

      – efie
      Dec 25 '18 at 23:53








    • 2





      @efie: char, short, int, and long are all integer types, and an integer is just a value, so I do not think their reference to a character as an integer is informative.

      – Eric Postpischil
      Dec 25 '18 at 23:54











    • That makes sense, thanks. Regarding your first comment: On page two the book says: "The second edition of The C Programming Language describes C as defined by the ANSI standard."

      – efie
      Dec 26 '18 at 0:02








    1




    1





    K&R precedes the C standard. Is there reason to believe that, in their text, the type of 'a' was int and not char?

    – Eric Postpischil
    Dec 25 '18 at 23:46





    K&R precedes the C standard. Is there reason to believe that, in their text, the type of 'a' was int and not char?

    – Eric Postpischil
    Dec 25 '18 at 23:46




    1




    1





    @EricPostpischil On page 37 the book says: "A character constant is an integer, written as one character within single quotes, such as 'x'". I'm not sure if "is an integer" means "is of type int"?

    – efie
    Dec 25 '18 at 23:53







    @EricPostpischil On page 37 the book says: "A character constant is an integer, written as one character within single quotes, such as 'x'". I'm not sure if "is an integer" means "is of type int"?

    – efie
    Dec 25 '18 at 23:53






    2




    2





    @efie: char, short, int, and long are all integer types, and an integer is just a value, so I do not think their reference to a character as an integer is informative.

    – Eric Postpischil
    Dec 25 '18 at 23:54





    @efie: char, short, int, and long are all integer types, and an integer is just a value, so I do not think their reference to a character as an integer is informative.

    – Eric Postpischil
    Dec 25 '18 at 23:54













    That makes sense, thanks. Regarding your first comment: On page two the book says: "The second edition of The C Programming Language describes C as defined by the ANSI standard."

    – efie
    Dec 26 '18 at 0:02





    That makes sense, thanks. Regarding your first comment: On page two the book says: "The second edition of The C Programming Language describes C as defined by the ANSI standard."

    – efie
    Dec 26 '18 at 0:02













    4














    K&R C is old. Really old. Many particulars of K&R C are no longer true in up-to-date standard C.



    In stadard, up-to-date C11, there is no conversion to/from char in the function you posted:



    /* lower: convert c to lower case; ASCII only */
    int lower(int c)
    {
    if (c >= 'A' && c <= 'Z')
    return c + 'a' - 'A';
    else
    return c;
    }


    The function accepts int arguments as int c, and per 6.4.4.4 Character constants of the C standard, character literals are of type int.



    Thus the entire lower function, as posted, under C11 deals entirely with int values.



    The conversion, if any, is may be done when the function is called:



    char upperA = 'A`;

    // this will implicitly promote the upperA char
    // value to an int value
    char lowerA = lower( upperA );


    Note that this is one of the differences between C and C++. In C++, character literals are of type char, not int.






    share|improve this answer
























    • Thanks! Do you know if a character constant was of type int in ANSI C as well? Or was it of type char which would add another explanation?

      – efie
      Dec 26 '18 at 0:43











    • Nothing whatsoever has changed about this function since C89.

      – n.m.
      Dec 26 '18 at 7:45
















    4














    K&R C is old. Really old. Many particulars of K&R C are no longer true in up-to-date standard C.



    In stadard, up-to-date C11, there is no conversion to/from char in the function you posted:



    /* lower: convert c to lower case; ASCII only */
    int lower(int c)
    {
    if (c >= 'A' && c <= 'Z')
    return c + 'a' - 'A';
    else
    return c;
    }


    The function accepts int arguments as int c, and per 6.4.4.4 Character constants of the C standard, character literals are of type int.



    Thus the entire lower function, as posted, under C11 deals entirely with int values.



    The conversion, if any, is may be done when the function is called:



    char upperA = 'A`;

    // this will implicitly promote the upperA char
    // value to an int value
    char lowerA = lower( upperA );


    Note that this is one of the differences between C and C++. In C++, character literals are of type char, not int.






    share|improve this answer
























    • Thanks! Do you know if a character constant was of type int in ANSI C as well? Or was it of type char which would add another explanation?

      – efie
      Dec 26 '18 at 0:43











    • Nothing whatsoever has changed about this function since C89.

      – n.m.
      Dec 26 '18 at 7:45














    4












    4








    4







    K&R C is old. Really old. Many particulars of K&R C are no longer true in up-to-date standard C.



    In stadard, up-to-date C11, there is no conversion to/from char in the function you posted:



    /* lower: convert c to lower case; ASCII only */
    int lower(int c)
    {
    if (c >= 'A' && c <= 'Z')
    return c + 'a' - 'A';
    else
    return c;
    }


    The function accepts int arguments as int c, and per 6.4.4.4 Character constants of the C standard, character literals are of type int.



    Thus the entire lower function, as posted, under C11 deals entirely with int values.



    The conversion, if any, is may be done when the function is called:



    char upperA = 'A`;

    // this will implicitly promote the upperA char
    // value to an int value
    char lowerA = lower( upperA );


    Note that this is one of the differences between C and C++. In C++, character literals are of type char, not int.






    share|improve this answer













    K&R C is old. Really old. Many particulars of K&R C are no longer true in up-to-date standard C.



    In stadard, up-to-date C11, there is no conversion to/from char in the function you posted:



    /* lower: convert c to lower case; ASCII only */
    int lower(int c)
    {
    if (c >= 'A' && c <= 'Z')
    return c + 'a' - 'A';
    else
    return c;
    }


    The function accepts int arguments as int c, and per 6.4.4.4 Character constants of the C standard, character literals are of type int.



    Thus the entire lower function, as posted, under C11 deals entirely with int values.



    The conversion, if any, is may be done when the function is called:



    char upperA = 'A`;

    // this will implicitly promote the upperA char
    // value to an int value
    char lowerA = lower( upperA );


    Note that this is one of the differences between C and C++. In C++, character literals are of type char, not int.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Dec 25 '18 at 23:50









    Andrew HenleAndrew Henle

    19.6k21333




    19.6k21333













    • Thanks! Do you know if a character constant was of type int in ANSI C as well? Or was it of type char which would add another explanation?

      – efie
      Dec 26 '18 at 0:43











    • Nothing whatsoever has changed about this function since C89.

      – n.m.
      Dec 26 '18 at 7:45



















    • Thanks! Do you know if a character constant was of type int in ANSI C as well? Or was it of type char which would add another explanation?

      – efie
      Dec 26 '18 at 0:43











    • Nothing whatsoever has changed about this function since C89.

      – n.m.
      Dec 26 '18 at 7:45

















    Thanks! Do you know if a character constant was of type int in ANSI C as well? Or was it of type char which would add another explanation?

    – efie
    Dec 26 '18 at 0:43





    Thanks! Do you know if a character constant was of type int in ANSI C as well? Or was it of type char which would add another explanation?

    – efie
    Dec 26 '18 at 0:43













    Nothing whatsoever has changed about this function since C89.

    – n.m.
    Dec 26 '18 at 7:45





    Nothing whatsoever has changed about this function since C89.

    – n.m.
    Dec 26 '18 at 7:45











    2















    How exactly is this function an example of a char to int conversion?




    /* lower: convert c to lower case; ASCII only */
    int lower(int c) {
    if (c >= 'A' && c <= 'Z')
    return c + 'a' - 'A';
    else
    return c;
    }


    It is not an example of a char to int conversion - technically incorrect by the author.





    The text goes on to discuss tolower(c) as an alternative to lower() as it "works" correctly even if [A -Z] are not consecutively encoded as in EBCDIC.



    What is not discussed, is that tolower() functions and others (is...()) are only specified for int values in the unsigned char range and EOF. C11 §7.4 1. Other values invoke undefined behavior (UB).



    It is this requirement that makes these Standard C library functions conceptually char to int conversions as only values in the (about) char range are specified and the result is int.





    Now look at code where char conversion does occur.



    void my_strtolower1(char *s) {
    while (*s) {
    *s = lower(*s); // conversion `char` to `int` and `int` to `char`.
    s++;
    }
    }

    void my_strtolower2(char *s) {
    while (*s) {
    *s = tolower(*s); // conversion `char` to `int` and `int` to `char`.
    s++;
    }
    }

    void my_strtolower3(char *s) {
    while (*s) {
    // conversion `char` to `unsigned char` to `int` and `int` to `char`.
    *s = tolower((unsigned char) *s);
    s++;
    }
    }


    my_strtolower1() well defined, yet not functionally correct on rare machines where [A-Z,a-z] are not consecutive.



    my_strtolower2() expected functionality except technically undefined behavior when *s < 0 (and not EOF).



    my_strtolower3() expected functionality without UB when *s < 0.






    share|improve this answer






























      2















      How exactly is this function an example of a char to int conversion?




      /* lower: convert c to lower case; ASCII only */
      int lower(int c) {
      if (c >= 'A' && c <= 'Z')
      return c + 'a' - 'A';
      else
      return c;
      }


      It is not an example of a char to int conversion - technically incorrect by the author.





      The text goes on to discuss tolower(c) as an alternative to lower() as it "works" correctly even if [A -Z] are not consecutively encoded as in EBCDIC.



      What is not discussed, is that tolower() functions and others (is...()) are only specified for int values in the unsigned char range and EOF. C11 §7.4 1. Other values invoke undefined behavior (UB).



      It is this requirement that makes these Standard C library functions conceptually char to int conversions as only values in the (about) char range are specified and the result is int.





      Now look at code where char conversion does occur.



      void my_strtolower1(char *s) {
      while (*s) {
      *s = lower(*s); // conversion `char` to `int` and `int` to `char`.
      s++;
      }
      }

      void my_strtolower2(char *s) {
      while (*s) {
      *s = tolower(*s); // conversion `char` to `int` and `int` to `char`.
      s++;
      }
      }

      void my_strtolower3(char *s) {
      while (*s) {
      // conversion `char` to `unsigned char` to `int` and `int` to `char`.
      *s = tolower((unsigned char) *s);
      s++;
      }
      }


      my_strtolower1() well defined, yet not functionally correct on rare machines where [A-Z,a-z] are not consecutive.



      my_strtolower2() expected functionality except technically undefined behavior when *s < 0 (and not EOF).



      my_strtolower3() expected functionality without UB when *s < 0.






      share|improve this answer




























        2












        2








        2








        How exactly is this function an example of a char to int conversion?




        /* lower: convert c to lower case; ASCII only */
        int lower(int c) {
        if (c >= 'A' && c <= 'Z')
        return c + 'a' - 'A';
        else
        return c;
        }


        It is not an example of a char to int conversion - technically incorrect by the author.





        The text goes on to discuss tolower(c) as an alternative to lower() as it "works" correctly even if [A -Z] are not consecutively encoded as in EBCDIC.



        What is not discussed, is that tolower() functions and others (is...()) are only specified for int values in the unsigned char range and EOF. C11 §7.4 1. Other values invoke undefined behavior (UB).



        It is this requirement that makes these Standard C library functions conceptually char to int conversions as only values in the (about) char range are specified and the result is int.





        Now look at code where char conversion does occur.



        void my_strtolower1(char *s) {
        while (*s) {
        *s = lower(*s); // conversion `char` to `int` and `int` to `char`.
        s++;
        }
        }

        void my_strtolower2(char *s) {
        while (*s) {
        *s = tolower(*s); // conversion `char` to `int` and `int` to `char`.
        s++;
        }
        }

        void my_strtolower3(char *s) {
        while (*s) {
        // conversion `char` to `unsigned char` to `int` and `int` to `char`.
        *s = tolower((unsigned char) *s);
        s++;
        }
        }


        my_strtolower1() well defined, yet not functionally correct on rare machines where [A-Z,a-z] are not consecutive.



        my_strtolower2() expected functionality except technically undefined behavior when *s < 0 (and not EOF).



        my_strtolower3() expected functionality without UB when *s < 0.






        share|improve this answer
















        How exactly is this function an example of a char to int conversion?




        /* lower: convert c to lower case; ASCII only */
        int lower(int c) {
        if (c >= 'A' && c <= 'Z')
        return c + 'a' - 'A';
        else
        return c;
        }


        It is not an example of a char to int conversion - technically incorrect by the author.





        The text goes on to discuss tolower(c) as an alternative to lower() as it "works" correctly even if [A -Z] are not consecutively encoded as in EBCDIC.



        What is not discussed, is that tolower() functions and others (is...()) are only specified for int values in the unsigned char range and EOF. C11 §7.4 1. Other values invoke undefined behavior (UB).



        It is this requirement that makes these Standard C library functions conceptually char to int conversions as only values in the (about) char range are specified and the result is int.





        Now look at code where char conversion does occur.



        void my_strtolower1(char *s) {
        while (*s) {
        *s = lower(*s); // conversion `char` to `int` and `int` to `char`.
        s++;
        }
        }

        void my_strtolower2(char *s) {
        while (*s) {
        *s = tolower(*s); // conversion `char` to `int` and `int` to `char`.
        s++;
        }
        }

        void my_strtolower3(char *s) {
        while (*s) {
        // conversion `char` to `unsigned char` to `int` and `int` to `char`.
        *s = tolower((unsigned char) *s);
        s++;
        }
        }


        my_strtolower1() well defined, yet not functionally correct on rare machines where [A-Z,a-z] are not consecutive.



        my_strtolower2() expected functionality except technically undefined behavior when *s < 0 (and not EOF).



        my_strtolower3() expected functionality without UB when *s < 0.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Dec 26 '18 at 7:42

























        answered Dec 26 '18 at 7:33









        chuxchux

        82k871148




        82k871148






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53926270%2fhow-exactly-is-this-function-an-example-of-a-char-to-int-conversion%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Plaza Victoria

            Puebla de Zaragoza

            Musa