Narue 5,707 Bad Cop Team Colleague

Isn't that like kind of general?

Yes, generalizations tend to be kind of general. :icon_rolleyes:

Narue 5,707 Bad Cop Team Colleague

Is the book called "ANSI C" by E. Balagurusamy informative?

It's a gross generalization, but in my experience, if the publisher is out of India, it raises red flags; I have yet to see a decent beginner's book on programming come out of India. Can you learn from these books? Absolutely. Will you pick up an excessive number of bad habits along the way? Very likely.

Go here and find a book that's either recommended or highly recommended.

Narue 5,707 Bad Cop Team Colleague

whenever we define an explicit constructor , is it necessary to define a default constructor as well?

No, it's not necessary. However, the instant you use your class in a way that requires a default constructor, it becomes necessary unless one of your explicit constructors can be used as a default constructor:

class foo {
public:
    foo(int arg=0); // This can be used as a default constructor
};

because in one of my code i simply defined an explicit constructor without defining the default one,and i found an error

You're using the class in a way that requires a default constructor. I can't give you specifics because you didn't post the code.

Narue 5,707 Bad Cop Team Colleague

The IDE should automatically handle linking for source files in your project.

Narue 5,707 Bad Cop Team Colleague

If you don't define any constructors, the compiler will generate a default constructor for you (or make it appear as if one was generated). However, the instant you define an explicit constructor, that default constructor is not longer created.

As for why your class needs an explicit default constructor, clearly you're using the class in ways that require a zero argument constructor, yet you've also defined a two argument constructor.

Narue 5,707 Bad Cop Team Colleague

If the variable has external linkage, you can simply declare it in whatever file you want, provided you link with the object file of the variable's definition:

/* foo.c */
int my_var = 0; /* extern by default */
/* main.c */
#include <stdio.h>

extern int my_var;

int main(void)
{
    printf("%d\n", my_var);
    my_var = 12345;
    printf("%d\n", my_var);

    return 0;
}

This is essentially what headers do: provide declarations for external definitions.

Narue 5,707 Bad Cop Team Colleague

The static declaration, applied to an external variable or function, limits the scope of that object to the rest of the source file being compiled.

The term "file" is somewhat misleading. The correct term is "translation unit", which is the fully preprocessed input to your compiler. Because of headers, multiple files can result in one translation unit.

In your case the two files are lumped together during preprocessing into a single translation unit, and that's how the static scope of y extends to both file.

Narue 5,707 Bad Cop Team Colleague

I have been following a book named "Let Us C" by Yashavant Kanetkar.

I haven't heard good things about that particular book.

I can't find out the topic "Sequence Point Rule" in here.

That's because your book is for beginners and sequence points are a concept that isn't strictly necessary when first learning the language.

Narue 5,707 Bad Cop Team Colleague

I have ran this program on my compiler DEV C++.
I also get same result=8
I have compiled many times...and It shows same output...

The problem with undefined behavior is that it's 100% unpredictable. The results could be intuitive or not. The results could be consistent or not. It could run perfectly for a year, then blow up when you're demoing your program to someone who wants to buy it. It could blow up immediately, then magically start working when you try to troubleshoot.

The lesson here is do not invoke undefined behavior.

So there is specific thing is going wrong...

Yes. What's wrong is no longer bound by the rules of C++ and can behave however the author of the compiler chose to handle such expressions, or if the author did not explicitly handle such expressions, whatever behavior falls out of the compiler's expression logic.

Can you explain more about "sequence point rule"...or give some good reference?

http://en.wikipedia.org/wiki/Sequence_point

Narue 5,707 Bad Cop Team Colleague

All the results does not match up with my understanding of C.

This is because you haven't yet learned the sequence point rule concerning modifications. The rule states that an object may be modified at most one time between sequence points, otherwise the result is undefined behavior. The + operator does not act as a sequence point, and ++ modifies the object.

So, in your first example you're modifying n1 twice between sequence points, and in your second example n1 is being modified thrice. Undefined behavior means that a compiler can do pretty much anything, so don't count on any kind of predictable result even on the same compiler. Technically, you could run this program twice and get different results.

Narue 5,707 Bad Cop Team Colleague

But the number I need need to be respectively smaller than 4 and 13, so what happens if the number that we get from the clock is bigger than those?

Completely irrelevant. You use srand to seed the random number generator. The current time is typically used because it's constantly changing and as such, gives you a different seed (and subsequently, a completely different random sequence) each time.

rand always returns a number between 0 and RAND_MAX, and you're using arithmetic tricks to shrink that range into your desired 0 to 4 and 0 to 13. So the seed only affects the sequence of random numbers you get from rand, not the range.

Narue 5,707 Bad Cop Team Colleague

im not allowed to do such complicated way~~

Then don't try to do complicated things. :D

Narue 5,707 Bad Cop Team Colleague

btw, i dont want to change the input type from long to char

Do you mind an intermediate step where the input is taken as a string and then converted to long? You'd have much more control that way:

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

int main(void)
{
    char line[BUFSIZ];

    printf("Enter a number: ");
    fflush(stdout);

    if (fgets(line, sizeof line, stdin) != NULL && line[0] != '\n') {
        char *end;
        long input;

        line[strcspn(line, "\n")] = '\0';
        errno = 0;
        input = strtol(line, &end, 0);

        if (!(errno == 0 && *end == '\0'))
            fprintf(stderr, "Invalid input [%s]\n", line);
        else
            printf("You entered %ld\n", input);
    }

    return 0;
}

That function does no error checking.

It does do error checking, and quite well too. The problem is that scanf is limited in terms of lookahead for validating the next character as well as limited in terms of determining if such a lookahead approach is even what the programmer wanted.

Narue 5,707 Bad Cop Team Colleague

The standard says that angle brackets cause the compiler to look in an implementation-defined location and double quotes cause the compiler to look in an implementation-defined location. I can see how there might be confusion. ;)

Traditionally the angle brackets searched the compiler's include locations followed by local directories, while double quotes did the opposite. Best practice has been to use angle brackets for compiler provided headers and double quotes for everything else.

Narue 5,707 Bad Cop Team Colleague

However it doesn't say if a similar strategy is used in case of multilevel inheritance

While there is an adjustment involved for multilevel inheritance in the case of casts, the thunk solution isn't needed and would be too heavy. For example:

struct Top { int a; };
struct Middle: Top { int b; };
struct Bottom: Middle { int c; int d; };

int main()
{
    Top *p = new Bottom;
}

In the typical implementation of single inheritance, new levels are simply appended to the object. So the object pointed to by p would look something like this:

-----
p -> | a |
     -----
     | b |
     -----
     | c |
     | d |
     -----

To access each of the data members below the top-level base you'd need a cast to force visibility, and that cast involves an offset to the appropriate sub-object:

p->a = 0;
((Middle*)p)->b = 1;
((Bottom*)p)->c = 2;
((Bottom*)p)->d = 3;

The adjustment upon casting is equivalent to adding an offset corresponding to the size of the object stack above the object you're casting to, followed by an offset into the object to get to the specified data member:

const int _Top_offset = sizeof(Top);
const int _Middle_offset = sizeof(Middle);

const int _Top_a_offset = 0;
const int _Middle_b_offset = 0;
const int _Bottom_c_offset = 0;
const int _Bottom_d_offset = sizeof(int);

*(int*)(((char*)p + 0) + _Top_a_offset) = 0;
*(int*)(((char*)p + _Top_offset) + _Middle_b_offset) = 1;
*(int*)(((char*)p + _Middle_offset) + _Bottom_c_offset) = 2; …
thelamb commented: Refreshing to have these kinds of questions/answers +3
Agni commented: Excellent explanation. Thanks +4
Narue 5,707 Bad Cop Team Colleague

Done.

Narue 5,707 Bad Cop Team Colleague

My interpretation of this is that comments are handled BEFORE macros like #if. Comments are parsed first and turned into whitespace. Thus the /* and */ take precedence over #if and #endif.

That's my interpretation as well, except from the standard's specified phases of translation instead of Wikipedia.

VernonDozier commented: Point taken. I'll source better in the future. +13
Narue 5,707 Bad Cop Team Colleague

"rhythm" is already taken. Do you have any alternatives that are less common?

Narue 5,707 Bad Cop Team Colleague

You can certainly ask questions about flowcharting. The best place would probably be the Computer Science forum.

Narue 5,707 Bad Cop Team Colleague

Python is designed to be friendly and concise, though for this problem I wouldn't say that C++ fares too badly in the comparison:

#include <algorithm>
#include <cctype>
#include <cstdlib>
#include <ctime>
#include <functional>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <sstream>
#include <stdexcept>
#include <string>
#include <vector>

namespace jsw {
    template <typename To, typename From>
    To lexical_cast(const From& rhs)
    {
        std::stringstream conv;
        To result;

        if (!(conv<< rhs && conv>> result))
            throw std::runtime_error("Bad lexical_cast");

        return result;
    }

    template <typename T>
    std::vector<T> split(const std::string& src, char delim)
    {
        std::istringstream splitter(src);
        std::vector<T> result;
        std::string field;

        while (std::getline(splitter, field, delim))
            result.push_back(jsw::lexical_cast<T>(field));

        return result;
    }

    template <typename T>
    std::string join(const std::vector<T>& src, char delim)
    {
        std::string result;

        for (std::vector<T>::size_type i = 0; i != src.size(); i++) {
            result += jsw::lexical_cast<std::string>(src[i]);

            if (i != src.size() - 1)
                result += delim;
        }

        return result;
    }
}

namespace {
    struct random_lotto {
        int operator()() { return 1 + rand() % 49; }
    };
}

int main()
{
    using namespace std;

    typedef vector<int> pick_t;
    typedef vector<pick_t> pick_list_t;

    ifstream in("test.txt");

    if (in) {
        pick_list_t lotto_picks;
        string line;

        // Get the lottery picks from file and extract into a convenient testing format
        while (getline(in, line)) {
            lotto_picks.push_back(jsw::split<pick_t::value_type>(line, '-'));
            sort(lotto_picks.back().begin(), lotto_picks.back().end());
        }

        pick_t winning_numbers;

        // Generate this week's winning numbers
        srand((unsigned)time(0));
        std::generate_n(std::back_inserter(winning_numbers), winning_numbers.size(), random_lotto());

        bool good_input = false;
        string opt;
        function<bool(int)> counter;

        // Do a linear or binary search based on user input
        while (!good_input) {
            cout<<"Search for winners with (L)inear or (B)inary search: ";

            if (!getline(cin, opt) || …
TrustyTony commented: Thanks for sharing your knowledge! +13
Narue 5,707 Bad Cop Team Colleague

I think I knew that but got confused looking at the way the virtual function call was transformed in the example, something like (*ptr->vptr[4])(ptr), and ptr is the pointer to base type pointing to a derived class object.

There are two mechanisms going on here. You have the virtual type and the actual type. The virtual type is the type of the pointer or reference to your object. The actual type is the type of the object itself. These two types can be different, thanks to polymorphism.

If you have a pointer to a base class that actually points to an object of a derived class, you can call virtual member functions through the base class pointer and the virtual table mechanism will call the derived class override. But you can't call a member function that does not exist in the base class, virtual or not.

So we can say that access is determined by the virtual type, but behavior is determined by the actual type.

what stops the compiler from finding the address of a child class function which might be in the next slot in the table?

Each class has its own virtual table. The base class virtual table won't contain new virtual functions added in a child class.

How is the type of object used here to determine which functions are not a part of base class ?

The type of the object determines which virtual table is queried. Obviously you shouldn't get …

Narue 5,707 Bad Cop Team Colleague

const char *msg is a pointer to const char. char* const msg is a constant pointer to char. In the former case the object being pointed to is const and cannot be modified, but the pointer can be changed to point to another object. In the latter case the pointer is const and cannot be pointed to another object, but the object being pointed to may be modified.

A third case could be where both are const:

const char* const msg;
vedro-compota commented: +++++ +1
Narue 5,707 Bad Cop Team Colleague

That is awesome fast. I just refresh the networking forum page and what the guy posted is deleted. Mods are awesome

The current mod team is the best we've ever had. I think most members would be shocked at the volume of they go through in a ridiculously short amount of time. While the bad posts make me sad, the speed at which they're dealt with makes me happy. :)

Narue 5,707 Bad Cop Team Colleague

Sounds like he's lonely. Someone should give him a hug. ;)

Narue 5,707 Bad Cop Team Colleague

You can't access newfnc from a pointer to Base because it's not available for that type, regardless of which actual object type you're pointing to. This is where downcasting comes into the picture, because you need to safely determine that the pointer is actually pointing to a Derived object before trying to access unique members of that class.

Narue 5,707 Bad Cop Team Colleague

I'm not sure I understand the question. Can you give an example of what you expect to happen?

Narue 5,707 Bad Cop Team Colleague

you know that in c++ you cant use " & " alone for the "and" purpose right?

You can (with proper care), but it's not short circuited and tends to be confusing. I don't know anyone who would let & instead of && slide during a code review.

Narue 5,707 Bad Cop Team Colleague

I'll bet the guy has links in his signature. Spammers like to do this to raise their page rank in search engines. However, Daniweb doesn't expose signature links to search engine web crawlers, so the net effect of these spam posts is a little valueless fluff added to the thread.

It's generally not worth the effort of banning and deleting unless a signature spammer floods the forum. It's also somewhat difficult to differentiate between a legitimate member making inane comments and a sig spammer.

Narue 5,707 Bad Cop Team Colleague

I'm not sure as I haven't tested it, but I'd imagine your email settings are disabled. Go to your control panel, then edit options, and make sure "Receive Occasional Email from Daniweb" is checked.

Narue 5,707 Bad Cop Team Colleague

There's a newsletter emailed to members each month. As for the interview, it varies.

Narue 5,707 Bad Cop Team Colleague

You need to do the work in a separate thread from your UI. That way the UI is still responsive while long running tasks are being performed in the background. You don't have to make the background task faster, just alter users' perception of application performance by avoiding the "Not Responding" message.

As for the "finished product", if you're planning on distributing the program to other machines, an installer package (NSIS or Inno Setup, for example) would be a good idea. Otherwise you'll need to be very careful to distribute all of the dependencies.

Narue 5,707 Bad Cop Team Colleague

On a side note, is there any particular reason you're using the C library in C++ when "better" equivalents exist in the C++ library?

#include <algorithm>
#include <iostream>
#include <ostream>
#include <stdexcept>

template <typename T, int N>
class Sort {
    T _base[N];
    int _filled;
public:
    enum { SIZE = N };

    Sort(): _filled(0)
    {
        std::fill_n(_base, N, T());
    }

    void insert(T value)
    {
        if (_filled == N)
            throw std::runtime_error("No more room");

        _base[_filled++] = value;
    }

    void doSort()
    {
        std::sort(_base, _base + N);
    }

    template <typename T, int N>
    friend std::ostream& operator<<(std::ostream& out, const Sort<T, N>& s)
    {
        out<<'{';

        for (int i = 0; i < s.SIZE; i++) {
            out<< s._base[i];
            out<< (i < s.SIZE - 1 ? ',' : '}');
        }

        return out;
    }
};

int main() try {
    Sort<int, 5> s;
    int x;

    for (int i = 0; i < s.SIZE; i++) {
        if (!(std::cin>> x))
            throw std::invalid_argument("Invalid input or stream error");

        s.insert(x);
    }

    std::cout<< s <<'\n';
    s.doSort();
    std::cout<< s <<'\n';
}
catch (const std::exception& ex) {
    std::cerr<< ex.what() <<'\n';
}
Narue 5,707 Bad Cop Team Colleague

Error 1 is a little subtle. qsort expects a pointer to a function, which sortarr is not. Due to how C++ handles member functions, the type of the address of Sort::sortarr is different from a typical function pointer. Note that doing what the error suggests and using a pointer to a member will not work because that's a completely different pointer type from a pointer to a function.

You can correct the error by either hoisting sortarr out of the class:

int sortarr(const void *x, const void *y) 
{
    return (*(int*)x - *(int*)y);
}

class Sort {
public:
    void doSort()
    {
        qsort(array, index, sizeof(int), sortarr);
        for (i=0; i<index; i++)
        {
            printf("%d ", array[i]);
        }
    }
};

Or by making sortarr a private static (private because users of the class probably don't need to see it):

class Sort {
public:
    void doSort()
    {
        qsort(array, index, sizeof(int), sortarr);
        for (i=0; i<index; i++)
        {
            printf("%d ", array[i]);
        }
    }
private:
    static int sortarr(const void *x, const void *y) 
    {
        return (*(int*)x - *(int*)y);
    }
};

Both of these will give sortarr pointer to function status rather than member function status.

>scanf(&number);
This is not how scanf is called. You need a format string and then a list of objects to hold data conversions as specified in the format string. For an integer, that would be:

if (scanf("%d", &number) == 1) {
    /* Success */
}

What the error is saying is that the first argument is not …

Narue 5,707 Bad Cop Team Colleague

In my opinion, the best way to welcome someone is to treat them like any other community member. That means more than any welcome message or special treatment.

Narue 5,707 Bad Cop Team Colleague

So what are you expecting 0 to represent as a string?

Narue 5,707 Bad Cop Team Colleague

Right now? I'm good. I'm actually working on a project that involves writing new code, so I'm quite content. Prior to this I was doing client implementations and support, which is slightly less enjoyable than being repeatedly punched in the face.

Narue 5,707 Bad Cop Team Colleague

but the getline function on the compiler we're using for this class is broken

Visual C++ 6? If so, there's a knowledgebase article on how to fix it. You really have no choice but to use getline or some facsimile because in your example the payee string has multiple words separated by whitespace. The >> operator stops reading at whitespace, so "first financial" would be stored as "first" and leave "financial" in the stream.

Narue 5,707 Bad Cop Team Colleague

Structures are an aggregate type. You need an instance of the structure before you can access any members. Notice that rchild and lchild are referenced without any struct instance as if they were not members, You probably want something more like ptr->rchild , for example.

You also can't use a variable defined in another function. In this case you're trying to use root in main when it's defined in insert.

Might I suggest reading up on scoping rules for C?

Narue 5,707 Bad Cop Team Colleague

Let's say you have a structure definition struct { int x; } a[10]; . For the sake of indexing, a is a pointer, so you can get to an element through either the a[<index>] or *(a + <index>) methods. At that point you have a structure object, so the . operator is used:

a[2].x; // This works
(*(a + 2)).x; // This works too

You can do indexing to get the address as well, in which case you'd have a pointer to a structure object:

(&a[2])->x; // This works
(a + 2)->x; // So does this

In your tests you were digging too deep as far as levels of indirection, assuming this is an array of struct objects rather than an array of pointers to struct objects:

>pt[2]->structureElement
p[2] is presumably a structure object, not a pointer to a structure unless your struct looks like struct { T structureElement; } *pt[N]; . So instead of using the arrow operator, which only works on pointers to structures, you use the dot operator:

pt[2].structureElement

>(*pt[2]).structureElement
Once again, pt[2] is already a structure object, not a pointer, so you can't dereference it.

Narue 5,707 Bad Cop Team Colleague

can anyone explain me how to use the inline function in c++ code with example?

There are two ways, actually. The inline keyword is one:

// foo is explicitly inline
inline void foo()
{
    /* ... */
}

Another is for member functions defined inside of a class:

class foo {
public:
    // bar is implicitly inline
    void bar()
    {
        /* ... */
    }
};

But i want to use this inline function in my code.

Why? Inlining involves a cost, and it's a common misconception that there will always be performance improvements. The prevailing advice when it comes to inlining is to avoid it unless you can prove that the benefits outweigh the costs.

Macro invocations do not perform type checking, or even check that arguments are well-formed, whereas function calls usually do.

Preprocessor macros are textual replacements performed prior to compilation. Any type checking and such is performed, just not in a way that's easy to debug. You will[/] get warnings and errors for problematic code, but it's based on the preprocessed code rather than the original source.

In other words, you cannot make the macro return something which is not the result of the last expression invoked inside it.

It gets worse. If you want the macro to have its own scope like a function, you can't return anything at all without using an output variable. This is because the usual tricks for creating a scope don't evaluate to a result that can be …

Narue 5,707 Bad Cop Team Colleague

date: 03/21/2011
first name: John
Last name: Connor
Dollar amount: 21
Change: 14
payee: first financial

should output to:

03/21/2011          John Connor
21.14               first financial

With the current setup, you can use the length of the date as your field width because it will always be longer than the amount. However, in a more robust system, the amount could potentially be longer or shorter than the date, in which case it makes more sense to check both and use the longer of the two to set your field width:

#include <iostream>
#include <iomanip>
#include <string>

using namespace std;

int main()
{
    string date, first_name, last_name, dollars, cents, payee;

    cout<<"Date: ";
    getline(cin, date);
    cout<<"First name: ";
    getline(cin, first_name);
    cout<<"Last name: ";
    getline(cin, last_name);
    cout<<"Dollar amount: ";
    getline(cin, dollars);
    cout<<"Change: ";
    getline(cin, cents);
    cout<<"Payee: ";
    getline(cin, payee);
    cout<<'\n';

    int field_width = date.size();
    string amount = dollars + '.' + cents;

    if (amount.size() > field_width)
        field_width = amount.size();

    field_width += 10; // To match your specified output

    cout<< setw(field_width) << left << date << first_name <<' '<< last_name <<'\n'
        << setw(field_width) << left << amount << payee <<'\n';
}
Narue 5,707 Bad Cop Team Colleague

The str is a Constant String, I want to Convert it to character array.

To what end? What does a character array have that the string doesn't? As L7Sqr stated, there's no string type in C. Strings are represented by "arrays" of char, where the last character is '\0' and "array" could be either an actual array, or a simulated array.

I'm assuming you want to create a writable copy of this string, since I can't really think of any other reason to do this conversion that doesn't stem from a misunderstanding of how strings and arrays work in C. In that case, it's really just a matter of using dynamic allocation:

const char *str = (*env)->GetStringUTFChars(env, data, 0);
char *copy = malloc(strlen(str) + 1); /* +1 for the terminating '\0' */

if (copy == NULL) {
    /* Handle failure to allocate memory */
}

strcpy(copy, str);

The issue being not one of arrays vs. strings, but one of constness. The string coming from Java may not be in writable memory, so a mutable copy needs to be made.

The str in your above example is an array

It's a pointer, not an array. The pointer might refer to the 0th element of an array, but pointers and arrays are different enough that it's wise not to confuse them.

and can be used like one ( str[4] for instance)

Yes, though not in all cases. sizeof(str) won't work like it would with an array, nor would …

Narue 5,707 Bad Cop Team Colleague

It's a warning and it's quite irrelevant.

It's a warning, but hardly irrelevant. The warning tells me that either the author made a mistake and meant &ch, or was hoping %p would print a hexadecimal value and was trying to be clever. Either way, the code is wrong. The fix for the latter is to recognize that fprintf already supports hexadecimal output without subverting the type system:

fprintf(stdout, "%3x", ch);
Narue 5,707 Bad Cop Team Colleague

To answer the other half of the question, you're not allowed to post on Daniweb if your account is banned. It's the web forum equivalent of sitting in time-out.

Narue 5,707 Bad Cop Team Colleague

Alternatively, use isprint to determine if there's a printable representation of the character, and show the numeric value if there is not.

Narue 5,707 Bad Cop Team Colleague

One thing to note is that sizeof(unsigned char) is absolutely going to return 1, every time. You can simplify the expression by removing that part.

Now, when malloc returns NULL on a modern OS, that's typically indicator of fragmented memory. You have memory to spare, but it's fragmented into small enough chunks that the memory manager can't find a large enough chunk to fulfill your request. I'd start by tracing the value of OutputPtr[i].Texels to see exactly how much memory is being requested.

You could potentially get more detailed error information by calling perror immediately after malloc.

Narue 5,707 Bad Cop Team Colleague

I am not clear as to what a seed is

In the case of rand(), you can think of the seed as the starting point for generating pseudorandom numbers. Since pseudorandom numbers are deterministic, there has to be some initial value for the algorithm.

Its up to you to disprove it.

I already did. The standard requires nothing of the sort. In fact, the standard goes out of its way to make the representation unspecified. Seeing as how I could fairly easily disprove your claim by writing my own implementation that does something different, I wouldn't recommend putting the ball in my court.

Narue 5,707 Bad Cop Team Colleague

It returns the number of seconds since 1970

Perhaps on your implementation. Here's the specification for the time() function in its entirety:

7.23.2.4 The time function

Synopsis

1 #include <time.h>
time_t time(time_t *timer);

Description

2 The time function determines the current calendar time. The encoding of the value is
unspecified.

Returns

3 The time function returns the implementation’s best approximation to the current
calendar time. The value (time_t)(-1) is returned if the calendar time is not
available. If timer is not a null pointer, the return value is also assigned to the object it
points to.

Unspecified means the implementation can do whatever it wants as long as the choice is documented. Nowhere in the standard is "1970" or "epoch" mentioned. Further, because the representation of time_t is unspecified, the result of time() need not be in seconds. An implementor can choose to make time_t the number of Twinkies sold in the fiscal year as long as the other date/time functions behave as specified.

Ancient Dragon commented: absolutely correct +36
Narue 5,707 Bad Cop Team Colleague

so time() function (argument being null) returns what?

An unspecified arithmetic type containing the current system time in an unspecified format. Technically, using time to seed srand is non-portable due to the unspecifiedness of the time_t type and value.

Is there any communication between rand() and srand() function?

rand() uses and maintains the seed generated by srand().

Also, how do you define seeding?

Clicky.

Narue 5,707 Bad Cop Team Colleague

Clearly you didn't search very hard. The Windows API is C-based, with wrappers(MFC)/frameworks(.NET) sitting on top of it to support C++ and C#.