C Strings not returning from a function

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Ian Collins

    #16
    Re: C Strings not returning from a function

    Keith Thompson wrote:
    Ian Collins <ian-news@hotmail.co mwrites:
    >
    >>Keith Thompson wrote:
    >>
    >>>Ian Collins <ian-news@hotmail.co mwrites:
    >>>
    >>>>A C++ compiler should refuse to compile the line you snipped;
    >>>
    >>>A C compiler should refuse to compile it.
    >>>
    >>>Actually, that's not quite true. Attempting to initialize a char*
    >>>with a char** is a constraint violation. A conforming C compiler must
    >>>issue a diagnostic. Once it's done so, it's not required either to
    >>>accept or to reject the translation unit.
    >>>
    >>><OT>I *think* the rules are similar in C++, but I'm too lazy to search
    >>>through the C++ standard for the corresponding wording. In any case,
    >>>I *think* that Visual C++ can be used as a C compiler.</OT>
    >>>
    >><OT>In C++, you can't assign or initialise with incompatible types, it's
    >>an error.</OT>
    >>
    >>I can't see why C doesn't enforce the same rules, if you want to do an
    >>incompatibl e assignment, you can force the issue with a cast.
    >
    >
    C does enforce the same rules. An assignment between incompatible
    types is a constraint violation, requiring a diagnostic.
    >
    Rather feeble enforcement.
    A C compiler is never required to *reject* a translation unit unless
    it contains a "#error" directive. (Many implementation-specific
    extensions are implemented by giving meaning to code that would
    otherwise violate a constraint.)
    >
    Or contains an expression that isn't well formed. In C++, an assignment
    between incompatible types isn't well formed.

    --
    Ian Collins.

    Comment

    • Old Wolf

      #17
      Re: C Strings not returning from a function

      Ian Collins wrote:
      Keith Thompson wrote:
      A C compiler is never required to *reject* a translation unit unless
      it contains a "#error" directive. (Many implementation-specific
      extensions are implemented by giving meaning to code that would
      otherwise violate a constraint.)
      Or contains an expression that isn't well formed.
      No. A C compiler is not required to reject a translation unit that
      contains an expression that isn't well formed. Keith Thompson's
      statement was correct.

      Comment

      • Richard Heathfield

        #18
        Re: C Strings not returning from a function

        pkirk25 said:
        "0 error(s), 0 warning(s)"
        >
        Well, that means i can go to bed!
        No, it means it's time to crank up your warning level.

        --
        Richard Heathfield
        "Usenet is a strange place" - dmr 29/7/1999

        email: rjh at above domain (but drop the www, obviously)

        Comment

        • sven_tmp@computerscience.ch

          #19
          Re: C Strings not returning from a function

          Hi pkirk25

          if you write your FixString function with two pointer-Arguments,
          you don't have to make a return call.
          char * FixString(char *strIn, char *strOut)
          Other Solution:

          void FixString(char *strIn, char *strOut)
          {
          int i = 0;
          int j = strlen(strIn);

          for (i = 0; i <= j; ++i) {
          /* removing the cleanup code for brevity on usenet */
          strOut[i] = strIn[i];
          }
          printf("%s\n", strOut);
          }

          int main(void)
          {
          char *strOut = "This is a line from a web page <br>";
          int i = strlen(strOut);
          char *backBuff = malloc(i);
          FixString(strOu t, backBuff);

          printf("%s\n", backBack); /* Prints out the string
          perfectly */

          return 0;
          }


          Sven

          Comment

          • Richard Heathfield

            #20
            Re: C Strings not returning from a function

            sven_tmp@comput erscience.ch said:
            Hi pkirk25
            >
            if you write your FixString function with two pointer-Arguments,
            you don't have to make a return call.
            >
            >char * FixString(char *strIn, char *strOut)
            >
            Other Solution:
            >
            void FixString(char *strIn, char *strOut)
            {
            int i = 0;
            int j = strlen(strIn);
            Undefined behaviour. Bonus question: why?
            for (i = 0; i <= j; ++i) {
            /* removing the cleanup code for brevity on usenet */
            strOut[i] = strIn[i];
            }
            printf("%s\n", strOut);
            Undefined behaviour. Bonus question: why?
            }
            >
            int main(void)
            {
            char *strOut = "This is a line from a web page <br>";
            int i = strlen(strOut);
            Undefined behaviour. Bonus question: why?
            char *backBuff = malloc(i);
            Constraint violation. Bonus question: why?
            FixString(strOu t, backBuff);
            Undefined behaviour. Bonus question: why?
            >
            printf("%s\n", backBack); /* Prints out the string
            perfectly */
            Undefined behaviour. Bonus question: why?
            return 0;
            }
            At least you got main's return type right.

            --
            Richard Heathfield
            "Usenet is a strange place" - dmr 29/7/1999

            email: rjh at above domain (but drop the www, obviously)

            Comment

            • sven_tmp@computerscience.ch

              #21
              Re: C Strings not returning from a function

              Hi Richard,

              I was not thinking in every detail about the
              code pkirk25 posted. The main thing I wanted to say is that the
              return in the FixString-function is not needed.

              You always write about undefined behavior, I don't know exactly
              why but I suggest it is because of the use of unchecked
              pointer-variables.

              Can you give me the answers to your quetions?
              void FixString(char *strIn, char *strOut)
              {
              int i = 0;
              int j = strlen(strIn);
              >
              Undefined behaviour. Bonus question: why?
              >
              for (i = 0; i <= j; ++i) {
              /* removing the cleanup code for brevity on usenet */
              strOut[i] = strIn[i];
              }
              printf("%s\n", strOut);
              Undefined behaviour. Bonus question: why?
              char *strOut = "This is a line from a web page <br>";
              int i = strlen(strOut);
              Undefined behaviour. Bonus question: why?
              char *backBuff = malloc(i);
              Constraint violation. Bonus question: why?
              FixString(strOu t, backBuff);
              Undefined behaviour. Bonus question: why?
              printf("%s\n", backBack); /* Prints out the string
              perfectly */
              Undefined behaviour. Bonus question: why?
              At least you got main's return type right.
              Thank you :)

              Sven

              Comment

              • pkirk25

                #22
                Fixed version

                If I understand rightly, the original version needed help in 3 areas:
                1. Basic C logic - can't return pointer to local variable
                2. C style - working with pointers is often better than working with
                function returns
                3. Security - what if the input file has a huge mangled string?

                This is my effort to fix all three. It works so many thanks.

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

                #define STRING_MAX_SIZE 254 /* ample headroom here */

                /*
                Function that
                */
                int FixString(const char *strIn, /* string to fix */
                const char cToken, /* token to use */
                char *strOut) /* the fixed string */
                {
                int i = 0;
                int j = strlen(strIn);


                if (j STRING_MAX_SIZE )
                {
                printf("Input too big\n");
                return 1;
                }




                for (i = 0; i <= j; ++i)
                {
                /* The cleanup code */
                if (cToken != strIn[i])
                {
                strOut[i] = strIn[i];
                } else
                {
                /* the token is found */
                strOut[i] = '\0'; /* terminates the string */
                j = i; /* ends the loop */
                }
                }

                return 0;
                }

                int main(void)
                {
                char *strOut = "Moonglade-Alliance<br>";
                char cToken = '-';
                int i = strlen(strOut);

                char *backBuff = malloc(STRING_M AX_SIZE);
                int j = FixString(strOu t, cToken, backBuff);

                if (j 0)
                {
                printf("Somethi ng has gone wrong\n");
                return 1;
                } else
                {
                printf("%s\n", backBuff); /* show fixed string */
                return 0;
                }


                }

                Comment

                • Richard Heathfield

                  #23
                  Re: C Strings not returning from a function

                  sven_tmp@comput erscience.ch said:
                  Hi Richard,
                  >
                  I was not thinking in every detail about the
                  code pkirk25 posted. The main thing I wanted to say is that the
                  return in the FixString-function is not needed.
                  >
                  You always write about undefined behavior, I don't know exactly
                  why but I suggest it is because of the use of unchecked
                  pointer-variables.
                  >
                  Can you give me the answers to your quetions?
                  1) You don't have a prototype in scope for strlen (which, incidentally, does
                  *not* return int, so I don't know why you're using an int to catch its
                  return value), so compiler will not know to supply the required conversion
                  from size_t to int.

                  2) You don't have a prototype in scope for printf, which is a variadic
                  function.

                  3) See 1)

                  4) You don't have a prototype in scope for malloc, so the assignment is
                  illegal and must be diagnosed.

                  5) You're passing a potentially meaningless pointer to a function that
                  depends utterly on having a valid pointer to a certain minimum number of
                  bytes. Incidentally, you didn't allocate enough space for the null
                  terminator.

                  6) See 2)


                  --
                  Richard Heathfield
                  "Usenet is a strange place" - dmr 29/7/1999

                  email: rjh at above domain (but drop the www, obviously)

                  Comment

                  • Richard Heathfield

                    #24
                    Re: Fixed version

                    pkirk25 said:
                    #include <stdio.h>
                    #include <string.h>
                    #include <stdlib.h>
                    Huge win, well done.
                    #define STRING_MAX_SIZE 254 /* ample headroom here */
                    /*
                    Function that
                    */
                    int FixString(const char *strIn, /* string to fix */
                    const char cToken, /* token to use */
                    char *strOut) /* the fixed string */
                    {
                    int i = 0;
                    int j = strlen(strIn);
                    size_t would be better. Incidentally, you already measured the length of the
                    string, in main. Why not pass that length in as an argument, to save
                    recalculating it? (Measuring a string's length is O(n), so it's not
                    something you want to repeat if you can avoid it.)
                    for (i = 0; i <= j; ++i)
                    If you write to strOut[j], you're in trouble.
                    {
                    /* The cleanup code */
                    if (cToken != strIn[i])
                    {
                    strOut[i] = strIn[i];
                    Here, you write to strOut[j] (last time round the loop).
                    } else
                    {
                    /* the token is found */
                    strOut[i] = '\0'; /* terminates the string */
                    Here, too.
                    int i = strlen(strOut);
                    Why int? strlen doesn't return int.
                    >
                    char *backBuff = malloc(STRING_M AX_SIZE);
                    i + 1 would have been enough. But you want to check that it worked:

                    if(backBuff != NULL)
                    {

                    --
                    Richard Heathfield
                    "Usenet is a strange place" - dmr 29/7/1999

                    email: rjh at above domain (but drop the www, obviously)

                    Comment

                    • Harald van Dijk

                      #25
                      Re: C Strings not returning from a function

                      Richard Heathfield wrote:
                      sven_tmp@comput erscience.ch said:
                      char *backBuff = malloc(i);
                      >
                      Constraint violation. Bonus question: why?
                      A question: since the behaviour is undefined if you declare any
                      standard library function (and more) inappropriately , isn't the
                      compiler allowed to try and generate a proper declaration for malloc(),
                      and accept this code without any diagnostic?

                      Comment

                      • Richard Heathfield

                        #26
                        Re: C Strings not returning from a function

                        Harald van D?k said:
                        Richard Heathfield wrote:
                        >sven_tmp@comput erscience.ch said:
                        char *backBuff = malloc(i);
                        >>
                        >Constraint violation. Bonus question: why?
                        >
                        A question: since the behaviour is undefined if you declare any
                        standard library function (and more) inappropriately , isn't the
                        compiler allowed to try and generate a proper declaration for malloc(),
                        and accept this code without any diagnostic?
                        No, because a diagnostic message *must* be generated if the source code
                        breaks any syntax rule or violates any constraint - which this one does -
                        even if the compiler can silently fix the code and proceed with the
                        translation (which it may, at its discretion). To be totally clear, the
                        diagnostic message is required. A successful translation (which may or may
                        not do what the programmer intended) is not required, but is allowed. That
                        is, the compiler may accept the code, or reject it, and it may either
                        understand (and thus, presumably, fix) the code or misinterpret it; the
                        Standard allows any of those options.

                        --
                        Richard Heathfield
                        "Usenet is a strange place" - dmr 29/7/1999

                        email: rjh at above domain (but drop the www, obviously)

                        Comment

                        • Harald van Dijk

                          #27
                          Re: C Strings not returning from a function

                          Richard Heathfield wrote:
                          Harald van D?k said:
                          >
                          Richard Heathfield wrote:
                          sven_tmp@comput erscience.ch said:
                          char *backBuff = malloc(i);
                          >
                          Constraint violation. Bonus question: why?
                          A question: since the behaviour is undefined if you declare any
                          standard library function (and more) inappropriately , isn't the
                          compiler allowed to try and generate a proper declaration for malloc(),
                          and accept this code without any diagnostic?
                          >
                          No, because a diagnostic message *must* be generated if the source code
                          breaks any syntax rule or violates any constraint - which this one does -
                          even if the compiler can silently fix the code and proceed with the
                          translation (which it may, at its discretion).
                          I mostly agree, except for the "which this one does" part. I think
                          you're overlooking my point. I'm not so sure the standard specifies
                          that any constraint is violated, since the standard does not specify
                          what the effect of the implicit declaration of malloc() is.

                          Comment

                          • Richard Heathfield

                            #28
                            Re: C Strings not returning from a function

                            Harald van D?k said:
                            Richard Heathfield wrote:
                            >Harald van D?k said:
                            >>
                            Richard Heathfield wrote:
                            >sven_tmp@comput erscience.ch said:
                            char *backBuff = malloc(i);
                            >>
                            >Constraint violation. Bonus question: why?
                            >
                            A question: since the behaviour is undefined if you declare any
                            standard library function (and more) inappropriately , isn't the
                            compiler allowed to try and generate a proper declaration for malloc(),
                            and accept this code without any diagnostic?
                            >>
                            >No, because a diagnostic message *must* be generated if the source code
                            >breaks any syntax rule or violates any constraint - which this one does -
                            >even if the compiler can silently fix the code and proceed with the
                            >translation (which it may, at its discretion).
                            >
                            I mostly agree, except for the "which this one does" part. I think
                            you're overlooking my point. I'm not so sure the standard specifies
                            that any constraint is violated, since the standard does not specify
                            what the effect of the implicit declaration of malloc() is.
                            But it does. The (C90) standard requires that, in the absence of an explicit
                            declaration for a function, that function is treated as if it returned int.
                            So the compiler is required to treat malloc(i) as returning int (because we
                            don't have a prototype). This int is then assigned to a char *, and that's
                            what violates a constraint.

                            --
                            Richard Heathfield
                            "Usenet is a strange place" - dmr 29/7/1999

                            email: rjh at above domain (but drop the www, obviously)

                            Comment

                            • Richard Tobin

                              #29
                              Re: C Strings not returning from a function

                              In article <PL2dnSOay92Yj4 TYnZ2dnUVZ8tOdn Z2d@bt.com>,
                              Richard Heathfield <invalid@invali d.invalidwrote:
                              >I mostly agree, except for the "which this one does" part. I think
                              >you're overlooking my point. I'm not so sure the standard specifies
                              >that any constraint is violated, since the standard does not specify
                              >what the effect of the implicit declaration of malloc() is.
                              >But it does. The (C90) standard requires that, in the absence of an explicit
                              >declaration for a function, that function is treated as if it returned int.
                              So now we have an (implicit) incorrect declaration for a standard
                              library function, which results in undefined behaviour. Could that
                              undefined behaviour not include magically using a correct declaration
                              instead?

                              -- Richard

                              Comment

                              • Harald van Dijk

                                #30
                                Re: C Strings not returning from a function

                                Richard Heathfield wrote:
                                Harald van D?k said:
                                >
                                Richard Heathfield wrote:
                                Harald van D?k said:
                                >
                                Richard Heathfield wrote:
                                sven_tmp@comput erscience.ch said:
                                char *backBuff = malloc(i);
                                >
                                Constraint violation. Bonus question: why?

                                A question: since the behaviour is undefined if you declare any
                                standard library function (and more) inappropriately , isn't the
                                compiler allowed to try and generate a proper declaration for malloc(),
                                and accept this code without any diagnostic?
                                >
                                No, because a diagnostic message *must* be generated if the source code
                                breaks any syntax rule or violates any constraint - which this one does -
                                even if the compiler can silently fix the code and proceed with the
                                translation (which it may, at its discretion).
                                I mostly agree, except for the "which this one does" part. I think
                                you're overlooking my point. I'm not so sure the standard specifies
                                that any constraint is violated, since the standard does not specify
                                what the effect of the implicit declaration of malloc() is.
                                >
                                But it does. The (C90) standard requires that, in the absence of an explicit
                                declaration for a function, that function is treated as if it returned int.
                                And as soon as malloc() is declared as returning int, before malloc()'s
                                new declaration is used, the behaviour is undefined. Would you also say
                                a diagnostic is required for

                                #define IGNORE(x) /* nothing */

                                int main (void)
                                {
                                IGNORE(")
                                void *p = malloc();
                                IGNORE(")
                                }

                                After all, here too the standard specifies both that the behaviour is
                                undefined before malloc()'s result is used, and that there would be a
                                constraint violation if the behaviour weren't explicitly undefined.

                                Comment

                                Working...