Skip to main content
fix typo, formatting
Source Link

There is no reason to use /NODEFAULTLIB`/NODEFAULTLIB

  1. Use printf instead of rolling your solution. But since you are probably removing the standard library. Here you go.
  2. write does not promise that all bytes will be written. If the kernel buffers are smaller than the number of bytes to be written it will only write a few bytes. You have to address that in your stdoutFunction.
  3. You might want to create two different definitions for Windows and Linux and then choose which one to use based on a macro, instead of using macros in the same function. It makes the code easier to read. But that is just my style. People may differ.
  4. When writing parsing code, don't loop over the parse string character by character. Instead, think in terms of tokens. You can break your problem into tokenizing the format string and doing the correct stuff in a switch statement based on the toke. Liketoken, like below. It is much more clear than mixing wchar_t and char strings. It also leads to fewer bugs because you are focusing on printing a single in each case statement.

There is no reason to use /NODEFAULTLIB`

  1. Use printf instead of rolling your solution. But since you are probably removing the standard library. Here you go.
  2. write does not promise that all bytes will be written. If the kernel buffers are smaller than the number of bytes to be written it will only write a few bytes. You have to address that in your stdoutFunction.
  3. You might want to create two different definitions for Windows and Linux and then choose which one to use based on a macro, instead of using macros in the same function. It makes the code easier to read. But that is just my style. People may differ.
  4. When writing parsing code, don't loop over the parse string character by character. Instead, think in terms of tokens. You can break your problem into tokenizing the format string and doing the correct stuff in a switch statement based on the toke. Like below. It is much more clear than mixing wchar_t and char strings. It also leads to fewer bugs because you are focusing on printing a single in each case statement.

There is no reason to use /NODEFAULTLIB

  1. Use printf instead of rolling your solution. But since you are probably removing the standard library. Here you go.
  2. write does not promise that all bytes will be written. If the kernel buffers are smaller than the number of bytes to be written it will only write a few bytes. You have to address that in your stdoutFunction.
  3. You might want to create two different definitions for Windows and Linux and then choose which one to use based on a macro, instead of using macros in the same function. It makes the code easier to read. But that is just my style. People may differ.
  4. When writing parsing code, don't loop over the parse string character by character. Instead, think in terms of tokens. You can break your problem into tokenizing the format string and doing the correct stuff in a switch statement based on the token, like below. It is much more clear than mixing wchar_t and char strings. It also leads to fewer bugs because you are focusing on printing a single in each case statement.
added 982 characters in body
Source Link
Ajinkya Kamat
  • 1.3k
  • 4
  • 15

Use the standard library

There is no reason to use /NODEFAULTLIB`

  1. Use printf instead of rolling your own solution. But since you are probably removing the standard library. Here you go.
  2. write does not promise that all bytes will be written. If the kernel buffers are smaller than the number of bytes to be written it will only write a few bytes. You have to address that in your stdoutFunction.
  3. You might want to create two different definitions for Windows and Linux and then choose which one to use based on a macro, instead of using macros in the same function. It makes the code easier to read. But that is just my style. People may differ.
  4. YouWhen writing parsing code, don't loop over the parse string character by character. Instead, think in terms of tokens. You can break your problem into findingtokenizing the specifierformat string and doing the correct stuff in a switch statement based on the toke. Like below. It is much more clear than mixing wchar_t and char strings. It also leads to fewer bugs because you are focusing on printing a single in each case statement.
typedef enum {
    ConversionType_StringLiteral = 0,
    ConversionType_String,
    ConversionType_WideString,
    //...
    ConversionType_MAX
} ConversionType;
typedef struct ConversionSpecification {
    ConversionType type;
    size_t length;
    size_t precision;
}ConversionSpecification;
ConversionSpecification getFormatSpecification(const char* fmt){

}

int dumberPrintf(const char* fmt, ...) {

    va_list args;
    va_start(args, fmt);
    size_t bytesWritten = 0;
    while(*fmt){

        ConversionSpecification spec = getFormatSpecification(fmt);
        if(spec.type >= ConversionType_MAX){
            return -1;
        }

        switch(spec.type){
            case ConversionType_StringLiteral:
            {
                // Do string literal stuff
            }
            case ConversionType_String:
            {
                // Do string stuff
            }
            case ConversionType_WideString:
            {
                // Do wide string stuff stuff
            }
            default:

        }

        fmt += spec.length;`
    }

    va_end(args);

    return bytesWritten;
}

Use the standard library

There is no reason to use /NODEFAULTLIB`

  1. Use printf instead of rolling your own solution. But since you are probably removing the standard library. Here you go.
  2. write does not promise that all bytes will be written. If the kernel buffers are smaller than the number of bytes to be written it will only write a few bytes. You have to address that in your stdoutFunction.
  3. You might want to create two different definitions for Windows and Linux and then choose which one to use based on a macro, instead of using macros in the same function. It makes the code easier to read. But that is just my style. People may differ.
  4. You can break your problem into finding the specifier and doing the correct stuff in a switch statement. Like below. It is much more clear than mixing wchar_t and char strings.
typedef enum {
    ConversionType_StringLiteral = 0,
    ConversionType_String,
    ConversionType_WideString,
    //...
    ConversionType_MAX
} ConversionType;
typedef struct ConversionSpecification {
    ConversionType type;
    size_t length;
}ConversionSpecification;
ConversionSpecification getFormatSpecification(const char* fmt){

}

int dumberPrintf(const char* fmt, ...) {

    va_list args;
    va_start(args, fmt);
    size_t bytesWritten = 0;
    while(*fmt){

        ConversionSpecification spec = getFormatSpecification(fmt);
        if(spec.type >= ConversionType_MAX){
            return -1;
        }

        switch(spec.type){
            case ConversionType_StringLiteral:
            {
                // Do string literal stuff
            }
            case ConversionType_String:
            {
                // Do string stuff
            }
            case ConversionType_WideString:
            {
                // Do wide string stuff stuff
            }
            default:

        }

        fmt += spec.length;`
    }

    va_end(args);

    return bytesWritten;
}

Use the standard library

There is no reason to use /NODEFAULTLIB`

  1. Use printf instead of rolling your solution. But since you are probably removing the standard library. Here you go.
  2. write does not promise that all bytes will be written. If the kernel buffers are smaller than the number of bytes to be written it will only write a few bytes. You have to address that in your stdoutFunction.
  3. You might want to create two different definitions for Windows and Linux and then choose which one to use based on a macro, instead of using macros in the same function. It makes the code easier to read. But that is just my style. People may differ.
  4. When writing parsing code, don't loop over the parse string character by character. Instead, think in terms of tokens. You can break your problem into tokenizing the format string and doing the correct stuff in a switch statement based on the toke. Like below. It is much more clear than mixing wchar_t and char strings. It also leads to fewer bugs because you are focusing on printing a single in each case statement.
typedef enum {
    ConversionType_StringLiteral = 0,
    ConversionType_String,
    ConversionType_WideString,
    //...
    ConversionType_MAX
} ConversionType;
typedef struct ConversionSpecification {
    ConversionType type;
    size_t length;
    size_t precision;
}ConversionSpecification;
ConversionSpecification getFormatSpecification(const char* fmt){

}

int dumberPrintf(const char* fmt, ...) {

    va_list args;
    va_start(args, fmt);
    size_t bytesWritten = 0;
    while(*fmt){

        ConversionSpecification spec = getFormatSpecification(fmt);
        if(spec.type >= ConversionType_MAX){
            return -1;
        }

        switch(spec.type){
            case ConversionType_StringLiteral:
            {
                // Do string literal stuff
            }
            case ConversionType_String:
            {
                // Do string stuff
            }
            case ConversionType_WideString:
            {
                // Do wide string stuff stuff
            }
            default:

        }

        fmt += spec.length;`
    }

    va_end(args);

    return bytesWritten;
}
added 982 characters in body
Source Link
Ajinkya Kamat
  • 1.3k
  • 4
  • 15

Use the standard library

There is no reason to use /NODEFAULTLIB`

  1. Use printf instead of rolling your own solution. But since you are probably removing the standard library. Here you go.
  2. write does not promise that all bytes will be written. If the kernel buffers are smaller than the number of bytes to be written it will only write a few bytes. You have to address that in your stdoutFunction.
  3. You might want to create two different definitions for Windows and Linux and then choose which one to use based on a macro, instead of using macros in the same function. It makes the code easier to read. But that is just my style. People may differ.
  4. Don't write everything in one function. It is confusing. If you got to cppreference and look up printf they have a table with format specifiers and expected arguments. You can break your problem into finding the specifier and callingdoing the correct function.
  5. You can then createstuff in a function table for different types and make your code very easy to readswitch statement. Like below. It is much more clear than mixing wchar_t and maintainchar strings.
typedef enum {
    ConversionType_StringLiteral = 0,
    ConversionType_String,
    ConversionType_WideString,
    //...
    ConversionType_MAX
} ConversionType;
typedef struct ConversionSpecification {
    ConversionType type;
    size_t length;
}ConversionSpecification;
ConversionSpecification getFormatSpecification(const char* fmt){

}

int dumberPrintf(const char* fmt, ...) {

    va_list args;
    va_start(args, fmt);
    size_t bytesWritten = 0;
    while(*fmt){

        ConversionSpecification spec = getFormatSpecification(fmt);
        if(spec.type >= ConversionType_MAX){
            return -1;
        }

        switch(spec.type){
            case ConversionType_StringLiteral:
            {
                // Do string literal stuff
            }
            case ConversionType_String:
            {
                // Do string stuff
            }
            case ConversionType_WideString:
            {
                // Do wide string stuff stuff
            }
            default:

        }

        fmt += spec.length;`
    }

    va_end(args);

    return bytesWritten;
}

Use the standard library

There is no reason to use /NODEFAULTLIB`

  1. Use printf instead of rolling your own solution. But since you are probably removing the standard library. Here you go.
  2. write does not promise that all bytes will be written. If the kernel buffers are smaller than the number of bytes to be written it will only write a few bytes. You have to address that in your stdoutFunction.
  3. You might want to create two different definitions for Windows and Linux and then choose which one to use based on a macro, instead of using macros in the same function. It makes the code easier to read. But that is just my style. People may differ.
  4. Don't write everything in one function. It is confusing. If you got to cppreference and look up printf they have a table with format specifiers and expected arguments. You can break your problem into finding the specifier and calling the correct function.
  5. You can then create a function table for different types and make your code very easy to read and maintain.

Use the standard library

There is no reason to use /NODEFAULTLIB`

  1. Use printf instead of rolling your own solution. But since you are probably removing the standard library. Here you go.
  2. write does not promise that all bytes will be written. If the kernel buffers are smaller than the number of bytes to be written it will only write a few bytes. You have to address that in your stdoutFunction.
  3. You might want to create two different definitions for Windows and Linux and then choose which one to use based on a macro, instead of using macros in the same function. It makes the code easier to read. But that is just my style. People may differ.
  4. You can break your problem into finding the specifier and doing the correct stuff in a switch statement. Like below. It is much more clear than mixing wchar_t and char strings.
typedef enum {
    ConversionType_StringLiteral = 0,
    ConversionType_String,
    ConversionType_WideString,
    //...
    ConversionType_MAX
} ConversionType;
typedef struct ConversionSpecification {
    ConversionType type;
    size_t length;
}ConversionSpecification;
ConversionSpecification getFormatSpecification(const char* fmt){

}

int dumberPrintf(const char* fmt, ...) {

    va_list args;
    va_start(args, fmt);
    size_t bytesWritten = 0;
    while(*fmt){

        ConversionSpecification spec = getFormatSpecification(fmt);
        if(spec.type >= ConversionType_MAX){
            return -1;
        }

        switch(spec.type){
            case ConversionType_StringLiteral:
            {
                // Do string literal stuff
            }
            case ConversionType_String:
            {
                // Do string stuff
            }
            case ConversionType_WideString:
            {
                // Do wide string stuff stuff
            }
            default:

        }

        fmt += spec.length;`
    }

    va_end(args);

    return bytesWritten;
}
Source Link
Ajinkya Kamat
  • 1.3k
  • 4
  • 15
Loading